我正在解决一些Java谜题并偶然发现了这个问题:
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {}
}
使用javac 1.6.0_45
编译此代码时,我按预期收到此错误:
Outer.java:8: cannot reference this before supertype constructor has been called
class Inner2 extends Inner1 {}
^
这是因为编译器为Inner2
类生成了具有类似代码的默认构造函数,这解释了上面的错误:
Inner2 () {
this.super();
}
现在很明显,因为你真的无法在Java 1.6.0_45,JLS 8.8.7.1中做到这一点(我可以猜到):
构造函数体中的显式构造函数调用语句可以 不引用任何实例变量或声明的实例方法 此类或任何超类,或在任何表达式中使用this或super; 否则,发生编译时错误。
请参阅accepted answer中的Odd situation for "cannot reference this before supertype constructor has been called")
但是如果我尝试用javac 1.7.0_79
编译它 - 那就没问题了!
这就是问题 - Java 1.7中的变化,这段代码现在是正确的吗?
提前致谢!
答案 0 :(得分:6)
看起来在Java bug跟踪器上讨论了与错误JDK-6708938: Synthetic super-constructor call should never use 'this' as a qualifier相同的问题。
此外,我认为您可以查看上一个相关问题,例如JDK-4903103: Can't compile subclasses of inner classes 。
注意两个错误的修正版本。
结果见Maintenance Review of JSR 901 (Java Language Specification) for Java SE 7。
来自The Java Language Specification Third Edition
否则,
S
是内部成员类(第8.5节)。这是一个编译时 如果S
不是词汇封闭类或成员的成员,则会出错 超类或超级接口。让O
成为最内在的词汇 封闭其中S
是成员的类,并让 n 为整数O
是 n 词汇封闭的C
类。马上 关于i
封闭S
的实例是词法 n 附上这个例子。
来自Java SE 7的JSR 901(Java语言规范)的维护评论(完整版,第242页,蓝色文本)或The Java Language Specification, Java SE 7 Edition中的相同内容(在第8.8.8节之前)
否则,S是内部成员类(§8.5)。
设O是S的最里面的词汇包围类,并且让n是O是的整数 第二个词汇封闭的C类。
立即封闭 关于S的i的实例是词汇封闭的第n个 这个例子。
所以你可以看到编译时错误的部分已经消失了。
答案 1 :(得分:-1)
我怀疑这与java 1.7中添加的invoke dynamic有关,以便为java 8中的lambda做准备。