以下代码按预期编译:
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>
还请参见:
答案 0 :(得分:5)
由于 B
不是静态的,它需要一些A
的实例才能存在,因此错误。
如果 B
是静态的,则错误消失。
将B更改为静态
添加构造函数
C() {
A.this.super();
}
然后它会起作用。
在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 ,所以它从C
到A
,因此代码适用于Java 7。
答案 1 :(得分:1)
这是一次递归 如果B扩展A,并且A本身有一个新的B,那么B将再次扩展A,依此类推......
正如@ZiyaoWei所提到的,当B为static
时,错误消失了。那是因为那时B级只会存在一次。