Research following method:
static private void foo() {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This code compiles good despite last catch block actually unreachable.
Now lets comment throw new FileNotFoundException();
row
execute:
OOOPs! we see
Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body
Strange. Why does java use double standards for these situatons?
static private void foo(FileNotFoundException f) {
try {
throw f;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
work as well as with constructor invocation
I noticed that on different versions of java compiler I see different result of compiling this code.
public class RethowTest {
public static void main(String[] args) {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
throw e;
}
}
}
on my local pc: java 1.7.0_45 -
C:\Program Files\Java\jdk1.7.0_45\bin>javac D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java
D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java:15: warning: unreachable catch clause
} catch (IOException e) {
^
thrown type FileNotFoundException has already been caught
1 warning
java 1.6.0_38
D:\DNN-Project\DNN-Project\src\main\java\exceptionsAndAssertions\RethowTest.java:16: unreported exception java.io.IOException; must be caught or declared to be thrown
throw e;
^
1 error
http://www.compileonline.com/compile_java_online.php (Javac 1.7.0_09) -
HelloWorld.java:9: warning: unreachable catch clause
} catch (IOException e) {
^
thrown type FileNotFoundException has already been caught
1 warning
Whenever an exception object is identified in a try block and if there are multiple catch blocks then the priority for the catch block would be given based on the order in which catch blocks are have been defined. Highest priority would be always given to first catch block.
Java Catch Multiple ExceptionsA try block can be followed by one or more catch blocks. Each catch block must contain a different exception handler. So, if you have to perform different tasks at the occurrence of different exceptions, use java multi-catch block.
No, multiple catch blocks cannot be executed. Once first catch block is catched, it will not read the next block.
You cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally. Still if you try to have single catch block for multiple try blocks a compile time error is generated.
The reachability rules are defined in the Java 8 JLS 14.21 (and Java 7) as follows:
A catch block C is reachable iff both of the following are true:
Either the type of C's parameter is an unchecked exception type or Exception or a superclass of Exception, or some expression or throw statement in the try block is reachable and can throw a checked exception whose type is assignable to the type of C's parameter. (An expression is reachable iff the innermost statement containing it is reachable.)
See §15.6 for normal and abrupt completion of expressions.
There is no earlier catch block A in the try statement such that the type of C's parameter is the same as or a subclass of the type of A's parameter.
Note that the rules DO NOT forbid your example code. The second catch block does not meet the criteria of the second bullet point.
(In the original version of the example, you caught Exception
. The reachability reasoning would be different, but the answer is the same - valid code.)
Is this inconsistent? For your example, you could argue that is the case.
Why didn't they address this case in the reachability rules? I don't know. You'd need to ask the Java designers!! However:
The formulation of the reachability rules would need to be significantly more complicated to handle this. Extra (unnecessary?) complexity in a specification is a concern.
You could argue that this inconsistency doesn't break anything. The reachability rules are really just a way of picking up potential errors in the users code. It doesn't involve type-safety or predictable execution; i.e. stuff that would "break" Java runtime semantics.
If they changed the spec now, that would render invalid a small proportion of valid and working Java programs. That's not a good idea, given that stability is one of the main selling points of Java.
On the other hand, I cannot think of a technical reason why they couldn't have addressed this "inconsistency" in the spec.
You noted that some Java compilers give a Warning message on the 2nd catch
. That is OK. A Java compiler is allowed to give warnings for things that are (technically) legal Java code.
If they were Errors, that would technically be a compiler bug ... according to my reading of the JLS.
The catch (Exception ...)
block will catch runtime exceptions. It's never unreachable in principle.
FileNotFoundException
is a checked exception. A catch block for it is only reachable if something in the try block throws it, or one of its child classes.
[in response to requests]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With