Why java does not detect unreachable catch block if I use multiple catch blocks?

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.