Summary
The javac
compiler is not in sync with a section of the language specification. In particular with JLS 18
section "§4.12.4 final Variables"
. This provokes that some programs that should be rejected according to the language spec are accepted by javac
Problem
javac
is not in sync with section §4.12.4
of the JLS 18
specification. In particular javac
is accepting as effectively final, variables that are the operand of increment or decrement operators. This provokes that javac
accepts programs that according to the spec should be rejected. As an example this code:
for (int i = 0; i < 10; i++) {
Runnable r = () -> System.out.println(i); // variable i is NOT effectively final
break; // even though "i++" is never reached
}
is being accepted by javac
when it should be rejected as variable i
is not effectively final and it is being accessed in the body of a lambda expression.
Solution
Synchronize javac with section §4.12.4
of the JLS 18
specification.
Specification
Of interest for this CSR is section §4.12.4
of the JLS 18
specification, titled: "final Variables"
in particular where it reads:
• A local variable declared by a statement and whose declarator has an initializer
(§14.4), or a local variable declared by a pattern (§14.30.1), is effectively final
if all of the following are true:
- It never occurs as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).
Note
The patch was ran through a corpus of Java source code, and there was only one project out of ~45000 that failed to compile due to this change.
- csr of
-
JDK-8294461 wrong effectively final determination by javac
-
- Resolved
-
- relates to
-
JDK-8299855 Revert JDK-8294461: wrong effectively final determination by javac
-
- Closed
-