Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning a default value to a final variable in case of an exception in Java

Why won't Java let me assign a value to a final variable in a catch block after setting the value in the try block, even if it is not possible for the final value to be written in case of an exception.

Here is an example that demonstrates the problem:

public class FooBar {

    private final int foo;

    private FooBar() {
        try {
            int x = bla();
            foo = x; // In case of an exception this line is never reached
        } catch (Exception ex) {
            foo = 0; // But the compiler complains
                     // that foo might have been initialized
        }
    }

    private int bla() { // You can use any of the lines below, neither works
        // throw new RuntimeException();
        return 0;
    }
}

The problem is not hard to work around, but I would like to understand why the compiler does not accept this.

Thanks in advance for any inputs!

like image 290
Alfonso Avatar asked Apr 08 '10 20:04

Alfonso


2 Answers

try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized
}

The reason is because the compiler cannot infer that the exception can only be thrown before foo is initalized. This example is a special case where it is obvious that that is true, but consider:

try {
    int x = bla();
    foo = x; // In case of an exception this line is never reached...or is it?
    callAnotherFunctionThatThrowsAnException();  // Now what?
} catch (Exception ex) {
    foo = 0; // But the compiler complains
             // that foo might have been initialized,
             // and now it is correct.
}

To write a compiler to handle very specific cases like this would be an immense task - there are likely very many of them.

like image 135
danben Avatar answered Oct 02 '22 19:10

danben


To be a pedant, Thread.stop(Throwable) could throw an exception immediately after the try block assignment.

However, the rules with definite assignment and allied terms are complex enough. Check the JLS. Trying to add more rules would complicate the language and not provide significant benefit.

like image 36
Tom Hawtin - tackline Avatar answered Oct 02 '22 21:10

Tom Hawtin - tackline