与私有方法冲突时调用接口中的默认方法

Calling default method in interface when having conflict with private method

考虑以下 class 层次结构。

class ClassA {
    private void hello() {
        System.out.println("Hello from A");
    }
}

interface Myinterface {
    default void hello() {
        System.out.println("Hello from Interface");
    }
}

class ClassB extends ClassA implements Myinterface {

}

public class Test {
    public static void main(String[] args) {
        ClassB b = new ClassB();
        b.hello();
    }
}

运行 程序会报如下错误:

Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.testing.ClassA.hello()V from class com.testing.Test
at com.testing.Test.main(Test.java:23)
  1. 这都是因为我将 ClassA.hello 标记为私有。
  2. 如果我将 ClassA.hello 标记为受保护或删除可见性修饰符(即使其成为默认范围),则它会显示一个编译器错误: The inherited method ClassA.hello() cannot hide the public abstract method in Myinterface

但是,根据上面的异常堆栈跟踪,我得到一个运行时 IllegalAccessError。

我不明白为什么这在编译时没有被检测到。有什么线索吗?

更新: 好像真的是bug.

class 或 super-class 方法声明总是优先于默认方法!

来自 Myinterface

default hello(...) 方法允许您无误地编写:

ClassB b = new ClassB();
b.hello();

直到运行时,因为在运行时 ClassA 中的 hello(...) 方法具有最高优先级(但该方法是私有的)。因此,IllegalAccessError出现。

如果从界面中删除默认的 hello(...) 方法,您会得到同样的非法访问错误,但现在是在编译时。