Community
Participate
Working Groups
I20080530-1730 On the following test case, javac raises an error and Eclipse does not: public class X { public static void main(String args[]) { final int i; do { try { break; } finally { i = 0; // javac error here } } while (args.length > 0); } } Reading JLS 3 $ 16.2.11 and $ 16.2.15, I believe that i is not definitely unassigned after the try statement because it is not definitely unassigned after the finally block, hence it is not definitely unassigned before the condition, hence it is not definitely unassigned after the condition when true, hence having it definitively unsigned before the try does not imply having it definitely unsigned after the condition, hence it is not definitively unsigned before the finally block, hence an error should be reported. In other words, I'd consider javac as right in this instance.
Added (inactive) AssignmentTest#58.
Let me grab this one. Perhaps in the next round of working on null/resource and other flow issues I'll get a chance to investigate this one as well. I already have a bunch of bugs relating to flow analysis for loops.
At a closer look into the spec I no longer think we should to change anything. The introduction of JLS 16 has this: The statement "V is definitely unassigned after X" (where V is a variable and X is a statement or expression) means "V is definitely unassigned after X if X completes normally". In this vein i *is* definitely unassigned after the try statement, because it is definitely unassigned after the try statement if the try statement completes normally. The try statement never completes normally due to the break, hence, *when* it completes normally (=never), i is definitely unassigned (and also definitely assigned). Ex falso omnis sequitur, as alluded to by the green-cheese-moon parable in the spec. IOW, the condition and also any subsequent (>1) iteration is unreachable, so there's no danger of re-assigning i. For documentation, javac8 reports: "error: variable i might be assigned in loop" which IMHO is not a sufficient reason for reporting an error. Finally, and for further illustration, here's what I believe to be an equivalent method, which is accepted by both compilers: //--- public static void m2(String args[]) { final int i; do { { // (1) inner : { // (2) break inner; } { // (3) i = 0; break; } } } while (args.length > 0); } //--- The blocks marked (1) - (3) emulate: (1) try-finally (2) try (3) finally The label-less break propagates whatever control flow brought us into the finally, the only option being: "break". I'll release an update of the disabled test once RC2 is out the door.
Test changes have been pushed via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=beded9a15cf855138f3e1c6f627196409b012ec5
Verified for 4.5 RC3.