JDK 1.7 vs JDK 1.6内部类继承差异

时间:2016-03-07 20:07:54

标签: java java-7 inner-classes java-6

我正在解决一些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中的变化,这段代码现在是正确的吗?

提前致谢!

2 个答案:

答案 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做准备。