Reachability and null analysis of assignment inside a try block with a throw inside the catch block
Alex Buckley
alex.buckley at oracle.com
Wed Oct 31 22:41:44 UTC 2018
On 10/31/2018 2:42 PM, Nir Lisker wrote:
> Given the following code:
>
> A getA() {
> A a = null;
> try {
> a = new A();
> } catch (ExceptionThrownByConstructor e) {
> throw e;
> }
> if (a != null) {
> return a;
> } else {
> ...
> }
> }
>
> If I understood the JLS correctly, the try-catch statement will either
> assign a non-null value to 'a' and continue, or will not continue
> (either rethrowing the checked exception or an unchecked exception
> occurs). If so, by the time the if condition is evaluated, 'a' is surely
> not null, so the else block should be unreachable, but it is not marked
> as such. Furthermore, removing the else block gives a compiler error
> that the method must return an object of type A, but this condition is met.
The JLS doesn't analyze the nullness of variables. The JLS does analyze
the reachability of statements. For your program, the rules in 14.21
work as follows: the `try` statement can complete normally, so the
succeeding `if` statement is reachable, so the `else` block is reachable.
Notwithstanding the fact that `a != null` is NOT a constant expression,
there is a lengthy explanation in JLS 14.21 of why the `else` block is
considered reachable.
If there is no `else` block, then the `if` statement can complete
normally. That violates the rule in 8.4.7 that "If a method is declared
to have a return type (§8.4.5), then a compile-time error occurs if the
body of the method can complete normally (§14.1)."
Alex
More information about the compiler-dev
mailing list