4

I am wondering what is the difference between throwing just Exception and throwing a specific Exception such as NullPointer Exception.

To my current knowledge an Exception should be able to catch any type of exception where as using a specific Exception expects that only that exception type can be thrown.

Example:

void test(String testString) throws Exception;

vs

void test(String testString) throws NullPointerException;

If this is correct than to me it makes sense to just always throw Exception and to never name a specific exception. Am I missing something important here? Does it at the very least effect performance at all? A lot of people are looking between throwing and catching exceptions but nobody asks this very basic question.

I do not see a benefit of throwing any exception except Exception.

halfer
  • 19,824
  • 17
  • 99
  • 186
L1ghtk3ira
  • 3,021
  • 6
  • 31
  • 70
  • 1
    You throw specific exceptions for specific cases. You want to throw specific exceptions to indicate that something specific has happened, not just to say "Hey, something didn't work, the application died but I have no clue why!" :) – Seth Jul 12 '16 at 14:57
  • What if your code can fail in several different ways, and some of those can be handled by the calling code and some can't? If you only throw `Exception`, how is the invoking code supposed to tell them apart? – azurefrog Jul 12 '16 at 14:57
  • 3
    Possible duplicate of [In Java, what is the difference between catch a generic exception and a specific exception (eg. IOException?)](http://stackoverflow.com/questions/5979501/in-java-what-is-the-difference-between-catch-a-generic-exception-and-a-specific) – azurefrog Jul 12 '16 at 14:59

4 Answers4

5

To start off, Exception is a base type of every Exception. Just like object is for everything.

By throwing a specific Exception you provide more information to the consumer of what has happened. Imagine scenario where you get a plain Exception without a message, consumer is lost. When for example framework throws a NullReferenceException, then you are aware of a fact that one of your objects does not have a reference which it was trying to access.

This is how you can chain exceptions and make use of their types:

try
{
   throw new NotImplementedException();
}
catch(NullReferenceException ex)
{
   // Logic for NullReference exception if needed.
}
catch(NotImplementedException ex)
{
   // This will be executed.
}
catch(Exception ex)
{
   // Will catch every exception.
}
Karolis Kajenas
  • 1,523
  • 1
  • 15
  • 23
  • 1
    Great example I see the importance of throwing specific Exceptions. Thanks a lot. If you think this post could help other beginners with throwing exceptions please vote the post up. If you also think I could make this post better let me know. – L1ghtk3ira Jul 12 '16 at 15:30
4

There are at least two reasons why you would want to throw a specific kind of exception:

  1. If a program fails with an exception, you will have more information with which to determine what went wrong. Compare seeing Exception with FileNotFoundException. The latter clearly gives you more information.
  2. In some cases, the code will want to catch certain kinds of exceptions. For example, when working with serial ports, you might want to catch and handle a TimeoutException differently from a NullReferenceException.
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thanks, I chose @Carl's because of the excellent example he added. Great information though so I still marked yours up. If you think this post will help other beginners with throwing exceptions please mark the post up. – L1ghtk3ira Jul 12 '16 at 15:28
  • If you also think I could make this post better let me know. – L1ghtk3ira Jul 12 '16 at 15:30
1

The NullPointerException you mentioned is a very good example from the regular Exception because it is a subclass of RuntimeException. Any throwing of (a subclass of) RuntimeException does not have to be caught or declared.

Any other (=not a subclass of RuntimeException) Exception has to be handled in your code by either a try/catch block or a throws declaration. Otherwise, your code will not even compile! That forces you as a developer to handle errors that might pop up.

As for why using different Exception types is useful, consider the following simple example that uses multiple catch statements:

void doDBStuff(){
  try {
    performStatement(someStatement);
  } catch(SQLException e){
    //invalid SQL syntax, something is broken
  } catch(AuthenticationException e){
    //invalid user credentials for the db, inform the user to change these values
  }

In this example, two different exceptions end up in two different catch blocks which lets you handle these errors differently.

f1sh
  • 11,489
  • 3
  • 25
  • 51
  • _"Otherwise, your code will not even compile!"_ - is that Java? –  Jul 12 '16 at 15:10
  • Yes. If you throw an ``IOException`` but neither catch nor declare it using ``throws``, you get a compilation error with the text "Unhandled exception type IOException". – f1sh Jul 12 '16 at 15:14
  • Sounds great. Thanks. +1 –  Jul 12 '16 at 15:16
  • Thanks, I chose @Carl's because of the excellent example he added. Great information though so I still marked yours up. If you think this post will help other beginners with throwing exceptions please mark the post up. – L1ghtk3ira Jul 12 '16 at 15:28
  • If you also think I could make this post better let me know. – L1ghtk3ira Jul 12 '16 at 15:30
0

It's a best practice to throw specific exceptions, instead of a generic one. This is because the caller might want to treat the exceptions differently, for example in a WebApi you might want to return a Bad Request response (400) for a ArgumentNullException, but you might want to return a different result for other types of exceptions. For example you might actually throw a custom NotFoundException and then the controller would catch it and return a Not Found response (404) instead. Basically if you throw specific exceptions you are allowing the consumer code to handle the different exception scenarios the way they want.

Rui Taborda
  • 170
  • 1
  • 3
  • 17