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

2022-09-01 02:12:35

考虑下面的类层次结构。

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。

我不明白为什么在编译时没有检测到这一点。任何线索?


答案 1

更新:似乎这真的是一个错误

类或超类方法声明始终优先于默认方法!

default hello(...)方法从 允许您编写没有错误:Myinterface

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

直到运行时,因为在运行时方法从 采取最高优先级 (但该方法是私有的)。因此,发生。hello(...)ClassAIllegalAccessError

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


答案 2

推荐