In Java, methods that throw checked exceptions (Exception or its subtypes - IOException, InterruptedException, etc) must declare throws statement:
public abstract int read() throws IOException;
Methods that do not declare throws
statement can't throw checked exceptions.
public int read() { // does not compile
throw new IOException();
}
// Error: unreported exception java.io.IOException; must be caught or declared to be thrown
But catching checked exceptions in safe methods is still legal in java:
public void safeMethod() { System.out.println("I'm safe"); }
public void test() { // method guarantees not to throw checked exceptions
try {
safeMethod();
} catch (Exception e) { // catching checked exception java.lang.Exception
throw e; // so I can throw... a checked Exception?
}
}
Actually, no. It's a bit funny: compiler knows that e is not a checked exception and allows to rethrow it. Things are even a bit ridiculous, this code does not compile:
public void test() { // guarantees not to throw checked exceptions
try {
safeMethod();
} catch (Exception e) {
throw (Exception) e; // seriously?
}
}
// Error: unreported exception java.lang.Exception; must be caught or declared to be thrown
The first snippet was a motivation for a question.
Compiler knows that checked exceptions can't be thrown inside a safe method - so maybe it should allow to catch only unchecked exceptions?
Returning to the main question - are there any reasons to implement catching checked exceptions in this way? Is it just a flaw in the design or am I missing some important factors - maybe backward incompatibilities? What could potentially go wrong if only RuntimeException
were allowed to be catched in this scenario? Examples are greatly appreciated.