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

时间:2018-04-02 11:57:28

标签: java java-8 default-method

考虑以下类层次结构。

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标记为protected或删除可见性修饰符(即使其成为默认范围),则它会显示编译器错误: The inherited method ClassA.hello() cannot hide the public abstract method in Myinterface
  3. 但是,根据上面的异常堆栈跟踪,我得到一个运行时IllegalAccessError。

    我无法理解为什么在编译时没有检测到这一点。有线索吗?

1 个答案:

答案 0 :(得分:29)

更新:好像它真的是bug

类或超类方法声明总是优先于默认方法!

来自default hello(...)

Myinterface方法允许您无误写入:

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

直到运行时,因为来自hello(...)的运行时ClassA方法具有最高优先级(但该方法是私有的)。因此,IllegalAccessError发生。

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

相关问题