When you access a final
variable from an anonymous class, the compiler secretly copies their value into a member variable of the anonymous class. eg:
Runnable foo() {
final int x = 42;
return new Runnable() {
void run() {
System.out.writeln(x);
}
};
}
becomes:
// the actual name is generally illegal in normal java syntax
class internal_Runnable implements Runnable {
final int x;
internal_Runnable(int _x) { x = _x; }
void run() {
System.out.writeln(x);
}
}
void foo() {
final x = 42;
return new internal_Runnable(x);
}
If the variable were not final and were allowed to change, the value cached in the anonymous class instance could go out of sync. This could have been avoided by use of a closure - that is, an object holding the values of all local variables, that both the original function and the new anonymous class instance access. .NET uses closures, for example. However, this can incur a performance hit, and perhaps for that reason, the Java language designers decided not to support full closures.