I'm still not satisfied with explanation regarding anonymous class and final field. There were tons of questions trying to explain obvious problem but I have not found answers for all my questions :-)
Suppose following code:
public void method(final int i, int j) {
final int z = 6;
final int x = j;
int k = 5;
new Runnable() {
public void run() {
System.out.print(i);
System.out.print(x);
System.out.print(z);
System.out.print(k);
}
};
}
- It's not possible to compile this code because of "unfinal"
k
property. - I understand that compiler can replace
z
property with the declared value during compile time.
When I've searched for solution how exactly can works i
and x
I found this answer which says:
The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, ofcourse), and you won't have the problem with accessing non-existent variables anymore
How it could work for fields i
and x
if they are parameters of the method? They are not known during compile time? This approach can work for z
.
On the other hand, there is an explanation regarding stack issues:
This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory
I would understand that anonymous class somehow copied all required content (fields) during it's creation. Missing final
has obvious problem that if some code below anonymous class declaration would change the value, the execution used possible stale
values.
But ok, this should solve the problem when anonymous class' method is executed out of scope of used properties.
But this approach should work even without final
declaration as it just copies all fields.
Both approaches seem like independent for me. Speaking of which - and it could solve my questions - I have not found how work final
method field. They are not removed from stack even if method gets finished? Seems like nonsense for me but it would explain lot of things :-)
What is the correct answer?