Ответ 1
Когда вы определяете такой анонимный класс внутри class AnonClass
:
AnonClass anon =
new AnonClass(12) {
{
System.out.println(super.x); //Prints 12
System.out.println(x); //prints 4
}
};
компилятор создаст класс примерно так:
class AnonClass$1 extends AnonClass {
final AnonClass enclosed;
AnonClass$1(AnonClass enclosed, int x) {
super(x);
System.out.println(super.x);
System.out.println(enclosed.x);
this.enclosed = enclosed;
}
}
а затем вызовите его так:
AnonClass anon = new AnonClass$1(this, 12);
Обратите внимание, что вызов суперконструктора (super(x);
) происходит до содержимого инициализатора экземпляра (строки System.out.println
).
Таким образом, поле AnonClass.x
инициализируется суперконструктором 12, а затем его значение печатается как 12
через System.out.println(super.x);
.
Затем System.out.println(x)
фактически ссылается на x
в прилагаемом экземпляре AnonClass
, значение которого равно 4.
Причина, по которой он не печатает 12
снова, заключается в том, что x
есть private
; и как говорится в JLS Sec 8.2:
Члены класса, объявленные как private, не наследуются подклассами этого класса.
Таким образом, нет AnonClass$1.x
для печати; единственным идентификатором в области под названием x
является AnonClass.x
.