【问题标题】:Strange compilation error with inner classes内部类的奇怪编译错误
【发布时间】:2013-06-13 14:11:15
【问题描述】:

以下代码按预期编译:

class A {
    class B {}
    class C extends B {}
}

但是,如果我们有类B 扩展类A,我们会收到一个编译错误:

class A {
    class B extends A {}
    class C extends B {}  // <-- Error here
}
由于一些中间体,没有可用的类型 A 的封闭实例 构造函数调用。

这里发生了什么?为什么扩展 A 会改变什么?

编辑: 显然,这在 Java 7 中编译得很好。我希望能解释一下为什么它不能在旧 Java 版本中编译,以及 Java 7 中发生了什么变化以允许它。


另请参阅:

【问题讨论】:

  • 请忘记整段废话——这是一个错误。 Javac 在这种情况下可以正常工作。我已经编辑了我的答案。 bugs.eclipse.org/bugs/show_bug.cgi?id=373371
  • @ZiyaoWei 这在 IntelliJ 中也不起作用
  • Javac 7 应该可以工作,如果不行,添加构造函数会有所帮助。
  • 发现骗局 - stackoverflow.com/questions/3383460/…,但此后情况发生了变化,因此我没有将其标记为骗局。仍在努力寻找相关信息。
  • 从 JLS 7 中找到参考,请参阅我编辑的答案。

标签: java compiler-errors inner-classes


【解决方案1】:

由于B 不是静态的,它需要A 的某个实例才能存在,因此出现错误。

如果B 是静态的,错误就会消失。

啊,别废话了。它是一个bug,它在Java7 模式下适用于ideone。但是,在 Java 7 之前它不起作用 - see this question,你需要要么

  1. 将 B 改为静态

  2. 添加构造函数

    C() {
        A.this.super();
    }
    

然后它就会工作。

在 Java 7 之前发生这种情况的原因可能是来自 JLS:

令 C 为被实例化的类,令 S 为 C 的直接超类,令 i 为正在创建的实例。

隐式super相对于S的i的直接封闭实例上调用

earlier JLS 中,直接封闭的实例定义为

令 O 是 S 是其成员的最内层的词法封闭类,并且令 n 是一个整数,使得 O 是 C 的第 n 个词法封闭类。关于 S 的 i 的直接封闭实例是第 n 个词法this 的封闭实例。

但是,在Java 7:

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

关于 S 的 i 的直接封闭实例是 this 的第 n 个词法封闭实例。

所以过去它是 S 是其成员的最内层的词法封闭类,而现在它是 S 的最内层的词法封闭类,所以它从CA,因此代码在 Java 7 中工作。

【讨论】:

  • 第二个就像再次调用自己,会导致它无限调用自己。递归。
【解决方案2】:

这是一个递归。
如果 B 扩展了 A,而 A 本身又有了一个新的 B,那么 B 会再次扩展 A,以此类推……

正如@ZiyaoWei 所述,当B 为static 时错误消失。那是因为 B 类只会存在一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2016-01-23
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多