I thought I knew the answer to this, but I can\'t find any confirmation after an hour or so of searching.
In this code:
public class Outer {
// othe
Only obj1
is captured.
Logically, the anonymous class is implemented as a normal class something like this:
class Anonymous1 extends SomeCallbackClass {
private final Outer _outer;
private final SomeObject obj1;
Anonymous1(Outer _outer, SomeObject obj1) {
this._outer = _outer;
this.obj1 = obj1;
}
@Override
public void onEvent() {
System.out.println(this.obj1.getName());
}
});
Note that an anonymous class is always an inner class, so it will always maintain a reference to the outer class, even if it doesn't need it. I don't know if later versions of the compiler have optimized that away, but I don't think so. It is a potential cause of memory leaks.
The use of it becomes:
someManager.registerCallback(new Anonymous1(this, obj1));
As you can see, the reference value of obj1
is copied (pass-by-value).
There is technically no reason for obj1
to be final, whether declared final
or effectively final (Java 8+), except that if it wasn't and you change the value, the copy wouldn't change, causing bugs because you expected the value to change, given that the copying is a hidden action. To prevent programmer confusion, they decided that obj1
must be final, so you can never become confused about that behavior.