【问题标题】:"java.lang.NoSuchFieldError: super" exception - bug in compiler?“java.lang.NoSuchFieldError: super”异常 - 编译器中的错误?
【发布时间】:2018-01-09 19:38:39
【问题描述】:

以下用 Java-9 编写的正在运行的代码在 runtime 中给了我一个非常奇怪和有趣的异常:

Exception in thread "main" java.lang.NoSuchFieldError: super
    at A$C.test(A.java:15)
    at A.main(A.java:5)

代码:

public class A {
    public static void main(String[] args) {
        new C().test();
    }

    interface B {
        private void test() {
        }
    }

    static class C implements B {
        void test() {
            B.super.test();
        }
    }
}

我想知道:是这样设计的,还是理想情况下不应该编译这段代码,因此这是一个编译器错误? (我个人认为这是一个错误)。

UPD:提交了一个错误,ID : 9052188

UPD-2:看起来B.super.test() 通常是一个有效的构造,因为如果test() 方法是default,那么它可以正常工作。这个事实只会让事情变得更复杂。

【问题讨论】:

  • 在这里猜测:A)这段代码是无效的(B超接口是一个接口,因此没有必要推迟到其中的方法的实现)和B)是的,编译器错误。所以合理的做法是:去写一个错误跟踪器问题;-)
  • 当然是编译器的bug。编译时没有错误且事后未进行操作的程序永远不应在运行时获得NoSuchFieldError(除非自己显式创建并抛出它),无论源代码是有效还是无效。
  • @GhostCat:不完全是。 B 有一个 private 方法,它是可访问的,因为它是一个嵌套类并且我们在同一个顶级类中。但我想,B.super.test() 不是正确的语法(但它是调用 default 方法的正确语法)。相比之下,((B)this).test() 绝对是有效的语法,也可以正常工作。
  • @Andremoniy 好吧,是的,如果不深入,我们可以假设这可能是一个 JVM 错误,但是,我更深入了。 super 访问永远不会使用名为super 的字段来实现,此外,当通过((B)this).test() 调用该方法时,它可以正常工作。剩下的唯一问题是B.super.test() 是否有效并且应该像((B)this).test() 那样编译,或者它是否无效并且应该被编译器拒绝。我倾向于后者。
  • already mentioned 认为 Interface.super.method() 是调用 default 方法的正确方法,但据我在 JLS 中看到的,它 only 用于调用default 方法。关于可访问性,JVM 绝不允许其他(普通)类访问private 方法。这就是编译器为嵌套类生成这些合成 access$n 方法的原因。 NoSuchFieldError 并不表示 JVM 拒绝了方法访问。

标签: java javac java-9 nosuchfieldexception


【解决方案1】:

最后这个问题被 Java 开发者支持团队承认为一个错误,这里是一个链接:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8194847

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多