繁体   English   中英

Java 中内部类的层次结构

[英]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.thisA的一个实例(试试这个代码: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM