Deepankar Singh
Deepankar Singh

Reputation: 674

Unreachable code- try-catch-finally

I know if java finds a line of code where it's guaranteed that control will never reach, then compiler reports unreachable code error.
consider following code.

    static int method1() {

        try{ return 1; }
        catch(Exception e){ }  // LINE-1
        finally{ }
        System.out.println("abc");  //LINE-2
        return 2;
    }
}

in above code
1 try block is guaranteed to exit by returning 1 but still lines after finally block (LINE-2 onwards) are reachable.
2. if i comment catch block (LINE-1), LINE-2 becomes unreachable.

Why is it so. Doesn't compiler able to see unconditional return in try block for case-1.

Upvotes: 1

Views: 6197

Answers (4)

khancock
khancock

Reputation: 147

You need to not think of the return statement within the try block, but think of the try block itself. It sees the try block and requires the catch to be there (optionally it can have a finally block). If you remove the catch statement, the try block doesn't know what to do if an error occurs, so anything below it will not be reached (Thus an unreachable code error)

The compiler thinks "Well, what happens to this code if the try block does output an error - well the code below it won't execute cause I have not been told how to recover from that error"

When you have a catch statement the compile kinda thinks like - I will try "CODE HERE" and if that goes wrong, I will catch the error and execute "CODE HERE" and optionally I will finally execute "CODE HERE". Then I will execute below the block like normal.

Upvotes: 1

David
David

Reputation: 218827

A try block (well, with a catch) tells the compiler that "what's in here may result in an exception". So the compiler assumes that, even though there are return statements therein, the try block might not successfully return.

Given that assumption, there are logical paths which would reach the catch and the finally. And since neither of those return, that same logical path would conclude the entire try/catch/finally entirely and result in reaching the code after it.

Basically, compilers (well, the designers thereof) prefer simple rules to complex ones. Simple rules are easier to test and support and be backward compatible with future versions. So while to a human who is analyzing the logic more thoroughly it's impossible to reach that code, to the compiler it's entirely possible.

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1500485

This is the relevant part of JLS 14.21:

A try statement can complete normally iff both of the following are true:

  • The try block can complete normally or any catch block can complete normally.

  • If the try statement has a finally block, then the finally block can complete normally.

In this case, although your try block can't complete normally, it has a catch block that can complete normally. The finally block can also complete normally.

The try statement is reachable and can complete normally, therefore the statement after it is reachable.

If you remove the catch block, the first bullet in the above quoted section is no longer true - which means the try statement can't complete normally, and the statement following it is unreachable.

Upvotes: 7

Susannah Potts
Susannah Potts

Reputation: 827

The compiler is seeing that you have a catch block for Exception and assuming it's possible for that to happen (because you told it that it could). Due to the fact that finally is reachable after the catch, the code following it is as well (as the catch block does nothing to terminate the function, and neither does finally). The second you comment out the catch, the compiler knows that it will never reach beyond finally in any condition, thus the error.

Upvotes: 1

Related Questions