与私有方法冲突时调用接口中的默认方法
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)
- 这都是因为我将 ClassA.hello 标记为私有。
- 如果我将 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(...)
方法,您会得到同样的非法访问错误,但现在是在编译时。
考虑以下 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)
- 这都是因为我将 ClassA.hello 标记为私有。
- 如果我将 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(...)
方法,您会得到同样的非法访问错误,但现在是在编译时。