6

Is it meaningful to declare a method to throw an exception and a subclass of this exception, e.g. IOException and FileNotFoundException?

I guess that it is used in order to handle both exceptions by a caller method differently. However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?

kon psych
  • 626
  • 1
  • 11
  • 26

6 Answers6

8

However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?

Absolutely. You can still catch them separately:

try {
  methodThrowingIOException();
} catch (FileNotFoundException e) {
  doSomething();
} catch (IOException e) {
  doSomethingElse();
}

So it makes no difference to what the caller can do if the method declares both - it's redundant. However, it can emphasize exceptions that you might want to consider. This could be done better in Javadoc than just the throws declaration.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Why is Javadoc better than code? Usually code is preferable to comments, are exceptions an exception? – Mark Oct 11 '19 at 08:01
  • @Mark: It's not *instead* of code. It's *as well as* the throws declaration. But you need the throws declaration in order to document the specific exceptions (IIRC). The point is that *just* using a throws declaration doesn't allow you to give any explanation - whereas javadoc does. – Jon Skeet Oct 11 '19 at 08:15
4

Is it meaningful to declare a method to throw an exception and a subclass of this exception, e.g. IOException and FileNotFoundException?

Usually not - most IDEs I know of even issue warnings for such declarations. What you can and should do is to document the different exceptions thrown in Javadoc.

However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?

Yes it is, you just need to ensure that the catch blocks are in the right order, i.e. more specific first. Catch blocks are evaluated in the order they are defined, so here

try {
  ...
} catch (FileNotFoundException e) {
  ...
} catch (IOException e) {
  ...
}

if the exception thrown is a FileNotFoundException, it will be caught by the first catch block, otherwise it will fall to the second and dealt with as a general IOException. The opposite order would not work as catch (IOException e) would catch all IOExceptions including FileNotFoundException. (In fact, the latter would result in a compilation error IIRC.)

Péter Török
  • 114,404
  • 31
  • 268
  • 329
0

However, is it possible to handle both exceptions if the method throws only the most generic i.e >IOException?

catch(IOException ex){
 if(ex instanceof FileNotFoundException){}
}

But this doesn't look clean, Throwing both exception looks good, even caller would come to know to that this method may throw these these exceptions, so they will handle it properly

jmj
  • 237,923
  • 42
  • 401
  • 438
  • You're right it's not clean - but it's not necessary, either. See my answer and Karthik's. Basically there's no need to have this ugliness. – Jon Skeet Jun 20 '12 at 09:51
  • @Jon if we declare method to throw IOException, how would caller come to know that it can also raise FileNotFoundException ? – jmj Jun 20 '12 at 09:52
  • It's not "also" - a FileNotFoundException *is* an IOException, so you can always try to catch it if the method declares that it throws IOException. It would be up to documentation to specify under what circumstances that occurs. – Jon Skeet Jun 20 '12 at 09:53
0

Yes, it's possible to handle both if the method only throws IOException.

The best way to answer such a question is to write a test to demonstrate it and try it out. Let the JVM tell you the answer. It'll be faster than asking here.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Actually the replies were quite fast and faster than it takes me to write a test class. My question had also another part and I hope it might be useful for others too. – kon psych Jun 20 '12 at 10:07
0

yes. when certain specialized exceptions can be handled correct. It is, if you handle the exceptions as follow:

try {
} catch (FileNotFoundException f) {
//Try a different file
} catch (IOException ioe) {
//Fatal, Maybe bad blocks ... Bail out... 
} catch (Exception e) {
//Something went wrong, see what it is...
}
0

Declaring, that the method may throw (more generic) IOException, and (more specific) FileNotFoundException is usually a good thing - it's an additional information for people using your code later. Note that you should explicitely state in the JavaDoc, under what circumstances is each of the exceptions thrown.

They will still be able to distinguish the exceptions, and handle them differently using catch constructs like this one:

try {
    yourAwesomeMethod()
} catch (FileNotFoundException ex) {
    // handle file-not-found error
} catch (IOException ex) {
    // handle other IO errors
}
npe
  • 15,395
  • 1
  • 56
  • 55