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

ar4*_*ers 17 java inner-classes java-6 java-7

我正在解决一些Java难题,并偶然发现了这个:

public class Outer {
    class Inner1 extends Outer {}
    class Inner2 extends Inner1 {}
}
Run Code Online (Sandbox Code Playgroud)

在编译此代码的同时,javac 1.6.0_45我正如预期的那样得到此错误:

Outer.java:8: cannot reference this before supertype constructor has been called
class Inner2 extends Inner1 {}                                                                                                
^
Run Code Online (Sandbox Code Playgroud)

这是因为编译器为Inner2具有类似代码的类生成默认构造函数,这解释了上面的错误:

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

现在很明显,因为你真的不能在Java 1.6.0_45,JLS 8.8.7.1中做到这一点(我可以猜到):

构造函数体中的显式构造函数调用语句可能不引用此类或任何超类中声明的任何实例变量或实例方法,或者在任何表达式中使用this或super; 否则,发生编译时错误.

请参阅(奇怪情况下接受的答案,"在调用超类型构造函数之前无法引用此内容")

但是,如果我尝试用javac 1.7.0_79它编译它- 它没关系!

这就是问题 - 在Java 1.7中已经改变了什么,这个代码现在是正确的?

提前致谢!

Nik*_*yev 6

看起来像JDK-6708938一样讨论了同样的问题:Synthetic超构造函数调用永远不应该使用'this'作为 Java bug跟踪器上的限定符.

另外我认为你看看前一个的其他相关问题会很好,例如JDK-4903103:无法编译内部类的子类 .

注意两个错误的固定版本.

结果参见Java SE 7的JSR 901(Java语言规范)的维护评论.

来自Java语言规范第三版

否则,S是内部成员类(第8.5节).如果S它不是词法封闭类的成员,或者是超类或超级接口的成员,则它是编译时错误.让O是最里面的词法封闭类,其中S是一个构件,并让Ñ是整数,使得OÑ个词法封闭类的C.的立即封闭实例i相对于SÑ个词法包围的这个实例.

来自Java SE 7的JSR 901(Java语言规范)的维护评论(完整版,第242页,蓝色文本)或Java语言规范中的相同内容,Java SE 7版(在第8.8.8节之前)

否则,S是内部成员类(第8.5节).

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

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

所以你可以看到带有编译时错误的部分已经消失了.