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