/* First of all, your program compiles and works fine because you are using Java 8.
If using Java 7 or lower, it won't even compile. The reason is exactly as you cited.
But I will try to explain it a bit more. Consider the following code: */
public void m1() {
int k = 30;
class inner {
public void m2() {
System.out.println(k);
}
}
inner o = new inner();
k = 42; // <= Note the reassignment here.
o.m2();
}
/*
What should the method call o.m2() print? "30" or "42"? Both outputs could
reasonably be argumented. At the time the method was declared and defined,
the variable k had the value 30. At the time the method was called, the
variable k had the value 42.
To prevent such ambiguities, the compiler does not allow assignment to a
variable that is used in such inner classes (local and anonymous). So it
must be final.
In Java 8 this was relaxed a bit. Java 8 introduced the concept of
effectively final. A variable that is declared and initialized and not
being assigned again is considered effectively final. And the compiler
allows that code without declaring the variable final.
As a matter of fact, you also get a compiler error in Java 8 when trying
to compile the above code.
*/