Вы можете заметить, что происходит внизу, просто декомпилируя внутренний класс. Вот краткий пример:
После компиляции этого фрагмента кода:
public class Test {
public void method() {
final Object handle = new Object();
Thread thread = new Thread() {
public void run() {
handle.toString();
}
};
thread.start();
}
}
вы получите Test.class
для Test.java
и Test$1.class
для внутреннего класса в Test.java
. После декомпиляции Test$1.class
вы увидите это:
class Test$1 extends Thread
{
final Test this$0;
private final Object val$handle;
public void run()
{
this.val$handle.toString();
}
}
Как видите, вместо handle
переменная this.val$handle
. Это означает, что handle
копируется как поле val$handle
во внутренний класс. И это будет работать правильно, только если handle
никогда не изменится - что в Java означает, что это должно быть final
.
Вы также можете заметить, что у внутреннего класса есть поле this$0
, которое является ссылкой на внешний класс. Это, в свою очередь, показывает, как нестатические внутренние классы могут взаимодействовать с внешними классами.