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

2022-09-03 02:55:51

我正在解决一些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;否则,将发生编译时错误。

请参阅(在奇数情况下接受的答案为“在调用超类型构造函数之前无法引用此值”)

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

这就是问题 - Java 1.7中发生了什么变化,这个代码现在是正确的?

提前致谢!


答案 1

看起来有关于与错误JDK-6708938相同的问题的讨论:合成超级构造函数调用永远不应该使用“this”作为Java错误跟踪器上的限定符。

另外,我认为您最好看看上一个相关的问题,例如JDK-4903103:无法编译内部类的子类

请注意这两个错误的修复版本。

结果请参阅 Java SE 7 的 JSR 901(Java 语言规范)维护评审

摘自 Java 语言规范第三版

否则,是内部成员类 (§8.5)。如果不是词法封闭类或其超类或超接口的成员,则为编译时错误。设为最内层的词法封闭类,其成员为成员,并设 n 为整数,即 为 的第 n 个词法封闭类。关于 的紧闭实例是此的第 n 个词法封闭实例。SSOSOCiS

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

否则,S 是内部成员类 (§8.5)。

设 O 是 S 的最内在词法封闭类,设 n 为整数,使得 O 是 C 的第 n 个词法封闭类。

i 相对于 S 的立即封闭实例是此的第 n 个词法封闭实例。

因此,您可以看到具有编译时错误的部分已经消失。


答案 2

我怀疑这与java 1.7中添加的调用动态有关,以便为java 8中的lambda做准备。


推荐