Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java unreachable catch block compiler error

Tags:

java

scjp

Why in Java can we catch an Exception even if it is not thrown, but we can't catch it's subclass (except for "unchecked" RuntimeExceptions and it subclasses). Example code:

class Test {
    public static void main(String[] args) {
        try {
            // do nothing
        } catch (Exception e) {
            // OK           
        }

        try {
            // do nothing
        } catch (IOException e) {
               // COMPILER ERROR: Unreachable catch block for IOException.
               //This exception is never thrown from the try statement body
        }       
    }
}

Any ideas?

like image 785
bary Avatar asked May 05 '11 14:05

bary


People also ask

How do I fix unreachable catch block error?

When we are keeping multiple catch blocks, the order of catch blocks must be from most specific to most general ones. i.e subclasses of Exception must come first and superclasses later. If we keep superclasses first and subclasses later, the compiler will throw an unreachable catch block error.

What is unreachable catch block error in Java?

A catch block C is reachable iff both of the following are true: Some expression or throw statement in the try block is reachable and can throw an exception whose type is assignable to the parameter of the catch clause C. (An expression is considered reachable iff the innermost statement containing it is reachable.)

How do you fix an unreachable error in Java?

1(a) is compiled, line 12 raises an unreachable statement error because the break statement exits the for loop and the successive statement cannot be executed. To address this issue, the control flow needs to be restructured and the unreachable statement removed, or moved outside the enclosing block, as shown in Fig.

What is unreachable statement error in Java?

Java Unreachable statement is an error according to the Java Language Spec . This error means that the control flow of your program can't get to that statement, but you assume that they would be. The compiler analyzes the flow, and reports these statements to you as error messages.


2 Answers

A RuntimeException could be thrown by any code. In other words, the compiler can't easily predict what kind of code can throw it. A RuntimeException can be caught by a catch(Exception e) block.

IOException, however, is a checked exception - only method calls which are declared to throw it can do so. The compiler can be (reasonably) confident that it can't possible occur unless there are method calls which are declared to throw it.

The Java compiler simply doesn't consider the "there's no code at all within the try block" situation - it always allows you to catch unchecked exceptions, as in all reasonable scenarios there will be code which could potentially throw an unchecked exception.

From section 14.21 of the JLS:

A catch block C is reachable iff both of the following are true:

  • Some expression or throw statement in the try block is reachable and can throw an exception whose type is assignable to the parameter of the catch clause C. (An expression is considered reachable iff the innermost statement containing it is reachable.)
  • 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.

Arguably the compiler should realize that there are no expressions within the try block in your first case... it looks like this is still an unreachable catch clause, to me.

EDIT: As noted in comments, section 14.20 contains this:

It is a compile-time error if a catch clause catches checked exception type E1 but there exists no checked exception type E2 such that all of the following hold:

  • E2 <: E1
  • The try block corresponding to the catch clause can throw E2
  • No preceding catch block of the immediately enclosing try statement catches E2 or a supertype of E2.

unless E1 is the class Exception.

So it looks like that's what you're actually running foul of, but the spec isn't as clear as it could be in terms of unreachable catch blocks in 14.21.

like image 171
Jon Skeet Avatar answered Sep 22 '22 10:09

Jon Skeet


IO Exceptions can only be caught if the compiler predicts that there might be something in the code that throws IOException. So you are getting a warning that IO exception is never thrown from the try statement body (since there is nothing in the body of try).

like image 37
Maveňツ Avatar answered Sep 23 '22 10:09

Maveňツ