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
-