Possible Duplicate:
Cannot refer to a non-final variable inside an inner class defined in a different method
What is the reason behind the rule of having local variables declared as final in order to access them from anonymous class?
final is the only allowed access modifier for local variables. final local variable is not required to be initialized during declaration. final local variable allows compiler to generate an optimized code. final local variable can be used by anonymous inner class or in anonymous methods.
Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.
An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final. Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name.
Accessing Members of an Enclosing Class In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final.
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.
...when an object of the anonymous class is instantiated, copies of the final local variables and method parameters referred to by the object's methods are stored as instance variables in the object. The methods in the object of the anonymous class really access those hidden instance variables.
Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.
From here.
An anonymous class is a separate class. It has no access to the control flow inside your method. If you would reassign the variable in the anonymous class, you would actually only reassign the anonymous class' copy of the variable. That would be very error-prone, and hence the design choice was made to make it an error.
If you want to work around that, use an AtomicReference
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With