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