内部类的奇怪编译错误

时间:2013-06-13 14:11:16

标签: java compiler-errors inner-classes

以下代码按预期编译:

class A {
    class B {}
    class C extends B {}
}

但是,如果我们有类B扩展类A,我们会收到编译错误:

class A {
    class B extends A {}
    class C extends B {}  // <-- Error here
}
No enclosing instance of type A is available due to some intermediate 
constructor invocation.

这里发生了什么?为什么扩展A会改变什么?

编辑:显然,这在Java 7中编译得很好。我希望能够解释为什么它不能在较旧的Java版本中编译,以及在Java 7中进行了哪些更改以允许它。< / p>


还请参见:

2 个答案:

答案 0 :(得分:5)

由于B不是静态的,它需要一些A的实例才能存在,因此错误。

如果B是静态的,则错误消失。

啊,忘了胡说八道。它是bug,在Java7模式下可以在ideone上运行。但是,在Java 7之前它不起作用 - see this question,你需要

  1. 将B更改为静态

  2. 添加构造函数

    C() {
        A.this.super();
    }
    
  3. 然后它会起作用。

    在Java 7之前发生这种情况的原因可能是来自JLS的以下内容:

      

    让C成为实例化的类,让S成为C的直接超类,让我成为正在创建的实例。

    隐式super关于S 的i的直接封闭实例上调用。

    earlier JLS中,立即封闭的实例定义为

      

    设O是最左边的词汇封闭类,其中S是一个成员,并且让n是一个整数,使得O是第n个词汇封闭的C类。关于S的i的直接封闭实例是词法上的第n个附上这个例子。

    然而,在Java 7

      

    设O是S的最里面的词汇封闭类,并且让n是一个整数,使得O是第n个词汇封闭的C类。

         

    关于S的i的直接封闭实例是第二个词汇封闭的实例。

    所以在过去,它是最里面的词汇封闭类,其中S是成员,而现在它是最里面的词汇封闭类S ,所以它从CA,因此代码适用于Java 7。

答案 1 :(得分:1)

这是一次递归 如果B扩展A,并且A本身有一个新的B,那么B将再次扩展A,依此类推......

正如@ZiyaoWei所提到的,当B为static时,错误消失了。那是因为那时B级只会存在一次。