[英]Hierarchy of inner classes in Java
我正在使用内部类的层次结构来表示应用程序中的一些数据,并且遇到了一条我根本不理解的错误消息。 我的代码可以归结为以下最小示例:
public class A {
public class B extends A {}
public class C extends B {}
}
Javac(当然还有我的 IDE)无法编译代码并显示以下错误消息:
A.java:3: cannot reference this before supertype constructor has been called
public class C extends B {}
^
1 error
我没有在任何地方写this
。 没有比上面提供的更多代码,所以我假设 javac 已经生成了与内部 class 相关的内容。
我找到了另一种表示我的数据的方法,所以我只是想很好地解释为什么它不能编译。
您需要一个外部 class 实例来创建一个内部 class 实例,即类似于new Outer().new Inner();
要使用另一个内部 class(子内部类)扩展内部 class(父内部类),您不能调用“父内部类”的构造函数,因为“外部类”的实例不存在。
像这样试试
public class A{
public class B extends A {
B() { }
}
public class C extends B {
C() {
new A().super();
}
}
public static void main(String args[]) {
}
}
类似的问题: “在调用超类型构造函数之前无法引用 this”的奇怪情况
另一张海报是正确的,但如何解决? 只需让您的 class static
:
public class A {
public static class B extends A {}
public static class C extends B {}
}
请注意,如果您的内部类引用外部 class 的字段,则不能将它们设为 static,否则您可以(并且应该 - 这样做会减少依赖性)。
您的代码在 Java 7 下编译。
以下变通方法在 Java 6 下编译。
public class C extends B
{
public C()
{
A.this.super();
}
}
@saugok 指向上一个问题的链接引用了 Joshua 的解释。 基本上他认为,由于 C 是 A 的子类,因此 C 继承 A 的成员作为 C 的成员。 因此 B 也是 C 的成员。 (For example a class literal C.B.class
is valid.) Therefore he argues that C.this
is the enclosing instance for B's super()
, therefore C(){super();}
is actually C(){C.this.super();}
。 由于C.this
无法在超级构造函数之前评估,因此出现错误。
但是,语言规范似乎并不保证这一点。 见#8.1.3。 Since B
is not immediately lexically enclosed by C
, B
is not a direct inner class of C
, there is no reason to say that B
's direct enclosing instance must be an instance of C
.
我们需要传递B()
一个A
的实例。 确实C.this
是A
的一个实例(试试这个代码: new C().new B().new C().new B();
)因此它可能是一个候选者。 还有另一个候选人A.this
。 A.this
可用并且可以使用(它作为隐藏参数传递给C()
)。
根据javap
, javac 7 将代码编译成
class B
private A this$0;
B( A a )
this$0 = a;
super(); // A()
class C extends B
private A this$0;
C( A a )
this$0 = a;
super( a ); // B(A)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.