Только obj1
захвачено.
Логически , анонимный класс реализован как обычный класс примерно так:
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());
}
});
Обратите внимание, что анонимный класс всегда является внутренним классом, поэтому он всегда будет поддерживать ссылку на внешний класс, даже если он ему не нужен. Я не знаю, оптимизировали ли это более поздние версии компилятора, но я так не думаю. Это потенциальная причина утечек памяти.
Использование становится:
someManager.registerCallback(new Anonymous1(this, obj1));
Как видите, справочное значение obj1
равно скопировано (передача по значению).
Технически нет причин для obj1
быть окончательным, независимо от того, объявлено ли final
или эффективно окончательно (Java 8+), за исключением того, что если это не так и вы меняете значение, копирование не изменится, что приведет к ошибкам, потому что вы ожидали, что значение изменится, учитывая, что копирование является скрытым действием. Чтобы избежать путаницы программистов, они решили, что obj1
должно быть окончательным, поэтому вы никогда не запутаетесь в этом поведении.