3

I know that the code below does make sense:

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

But does declaring those parent and child exceptions in the throws clause make sense?

Suppose I have the following code:

public void doSomething() throws FileNotFoundException, IOException { ... }

We all know that FileNotFoundException is a subclass of IOException. Now does it make sense in any way (readability, performance, et cetera) to declare it like that, opposing to just this:

public void doSomething() throws IOException { ... }
MC Emperor
  • 22,334
  • 15
  • 80
  • 130

2 Answers2

6

For the Java compiler, it doesn't matter whether a subclass is in the throws clause, because the superclass exception will cover it.

However, for documentation purposes it is important. The caller of your method may want to know that it can throw a subclass exception, e.g. FileNotFoundException, and handle it differently.

try {
    doSomething();
}
catch (FileNotFoundException e) {
    System.out.println("File not found!");
}
catch (IOException e) {
    System.out.println("An I/O error has occurred: " + e.getMessage());
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
1

Sometimes it makes sense to catch both exceptions, as long the the sub-class exception is specified first (otherwise, I think it won't even compile). It allows you to handle specific exceptions you care about in a different way than more general exceptions.

For example, I have code that reads from a socket. It's a blocking read, an I set a timeout, since there might be nothing to read. That's why I catch SocketTimeoutException and do nothing about it. If, on the other hand, I get other IOExceptions (IOException being an indirect super-class of SocketTimeoutException), I am throwing an exception, since a real failure happened while trying to read from the socket.

    catch (SocketTimeoutException ignEx) {
// -- ignore exception, as we are expecting timeout exceptions because
// -- there might be nothing to read
    }
    catch (IOException ioEx) {
      throw new SomeException (...);
    }

As for declaring both in the method signature, It is not necessary to declare both in the throws clause, but it would be useful to the users of your method if you document both exceptions in the JavaDoc comments, and describe the conditions in which each of them are thrown.

Eran
  • 387,369
  • 54
  • 702
  • 768