【发布时间】:2014-08-07 10:11:19
【问题描述】:
考虑以下Test 类来演示Java 中的内部类行为。主要代码在run 方法中。 Rest 只是管道代码。
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 指定的吗?
P.S:我知道内部类包含对外部类的隐藏引用,并且在上面的 javap 输出中设置了该引用。但问题是为什么它是在调用超级构造函数之前设置的。我错过了什么?
【问题讨论】:
-
按照规范,封闭实例可以从超类构造函数中访问。
标签: java inner-classes jls javap