Согласно JLS §15.9.5 :
Анонимный класс всегда является внутренним классом (§8.1.3); это никогда не будет c (§8.1.1, §8.5.1).
Обратите внимание, что в JLS нет исключений для случая, когда анонимный класс расширяет static
class.
Следовательно, он должен иметь ссылку на экземпляр включающего его класса.
Я упростил ваш пример, превратив его в законный автономный класс Java, скомпилировал его и посмотрел байт-коды для анонимного класса, используя javap -c
. Код конструктора делает ссылку на включающий класс и сохраняет в скрытом поле (this$0
).
class Concept {
public Inner func() {
return new Inner() {
@Override
protected Object bar() {
return new Object();
}
};
}
private abstract static class Inner {
protected abstract Object bar();
}
}
javap -c 'Concept$1.class'
Compiled from "Concept.java"
class Concept$1 extends Concept$Inner {
final Concept this$0;
Concept$1(Concept);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LConcept;
5: aload_0
6: invokespecial #2 // Method Concept$Inner."<init>":()V
9: return
protected java.lang.Object bar();
Code:
0: new #3 // class java/lang/Object
3: dup
4: invokespecial #4 // Method java/lang/Object."<init>":()V
7: areturn
}