考虑以下Test
类来演示 Java 中的内部类行为。主要代码在run
方法中。休息只是管道代码。
public class Test {
private static Test instance = null;
private Test() {
}
private void run() {
new Sub().foo();
}
public static void main(String[] args) {
instance = new Test();
instance.run();
}
class Super {
protected void foo() {
System.out.println("Test$Super.Foo");
}
}
class Sub extends Super {
public void foo() {
System.out.println("Test$Sub.Foo");
super.foo();
}
}
}
我只是在隐藏Sub
构造函数的 javap 输出下方打印:
so.Test$Sub(so.Test);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Lso/Test;
5: aload_0
6: aload_1
7: invokespecial #2 // Method so/Test$Super."<init>":(Lso/Test;)V
10: return
通常,编译器会确保子类构造函数首先调用超类构造函数,然后再继续初始化它自己的字段。这有助于正确构造对象,但在编译器为内部类生成的构造函数的情况下,我发现规范行为存在偏差。为什么这样?它是由 JLS 指定的吗?
PS:我知道内部类包含对外部类的隐藏引用,并且在上面的 javap 输出中设置了该引用。但问题是为什么它是在调用超级构造函数之前设置的。我错过了什么?