内部类的奇怪编译错误

ars*_*jii 4 java compiler-errors inner-classes

以下代码按预期编译:

class A {
    class B {}
    class C extends B {}
}
Run Code Online (Sandbox Code Playgroud)

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

class A {
    class B extends A {}
    class C extends B {}  // <-- Error here
}
Run Code Online (Sandbox Code Playgroud)
No enclosing instance of type A is available due to some intermediate 
constructor invocation.

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

编辑:显然,这在Java 7中编译得很好.我将理解为什么它不能在较旧的Java版本中编译以及Java 7中的更改以允许它.


也可以看看:

zw3*_*324 5

既然B不是静态的,它需要一些A能够存在的实例,从而产生错误.

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

啊,忘掉废话.这是一个错误,它适用于ideone在Java7模式.但是,在Java 7之前它不起作用 - 请参阅此问题,您也需要

  1. 将B更改为静态

  2. 添加构造函数

    C() {
        A.this.super();
    }
    
    Run Code Online (Sandbox Code Playgroud)

然后它会起作用.

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

设C是要实例化的类,让S成为C的直接超类,让我成为正在创建的实例.

对于S,在i的立即封闭的实例上super调用隐式.

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

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

但是,在Java 7中:

设O是S的最内层词汇封闭类,并且让n为整数,使得O是词汇包含C的第n个类.

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

所以在过去,它是最里面的词汇封闭类,其中S是一个成员,而现在它是S的最内部词汇封闭类,因此它从而C变为A,因此代码在Java 7中起作用.