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中的更改以允许它.
也可以看看:
既然B不是静态的,它需要一些A能够存在的实例,从而产生错误.
如果B是静态的,则错误消失.
啊,忘掉废话.这是一个错误,它适用于ideone在Java7模式.但是,在Java 7之前它不起作用 - 请参阅此问题,您也需要
将B更改为静态
添加构造函数
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中起作用.