【发布时间】:2020-06-30 19:53:58
【问题描述】:
如果三个公共接口定义为:
public interface One{}
public interface Two{}
public interface Three{}
另外一个类 Super 被定义为:
public class Super {
public static <E extends One & Two & Three> void hmm(E item) {}
}
为什么Super下面的子类会报编译错误?
public class Subber extends Super{
public static void hmm(One item) {}
}
我希望上述方法可以简单地对 Super 隐藏该方法,但事实并非如此。
JLS (8.4.8.2) 说:
如果类 C 声明或继承静态方法 m,则称 m 隐藏任何方法 m',其中 m 的签名是 m' 签名的子签名(第 8.4.2 节),在超类中和 C 的超接口,否则这些超接口可以访问(第 6.6 节)以用 C 编写代码。
其中子签名在 8.4.2 中定义为:
如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为M的类型参数,形式参数类型相同。
如果满足以下任一条件,方法 m1 的签名是方法 m2 签名的子签名: m2 与 m1 具有相同的签名,或者 m1 的签名与 m2 签名的擦除(第 4.6 节)相同.
根据 JLS 4.6,类型变量的擦除是其最左边界的擦除,因此: 据我了解,Subber 的 hmm 方法与 Super 的 hmm 方法的擦除相同,因此将是 Super 的 hmm 的子签名,因此意味着它会隐藏 Super 的 hmm。但是,我收到的错误消息(来自 eclipse),鉴于上述情况,这似乎没有意义:“Subber 类型的方法 hmm(One) 与 Super 类型的 hmm(E) 具有相同的擦除,但没有把它藏起来。”我错过了什么?
编辑:准确的错误消息,主要方法只包含Subber.hmm(null); 是:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Name clash: The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it
at base/testpack4.Subber.hmm(Subber.java:4)
at base/testpack4.Main.main(Main.java:5)
有人可以解释为什么 Subber 的方法无法编译,并引用可靠的来源(最好是 JLS)吗?
【问题讨论】:
-
能否包含编译器错误信息?
-
已添加,谢谢@matt b
-
您的 Java 版本是多少?我无法在 Java 14 上重现它。
-
可能是eclipse java编译器的bug
-
java.exe 和 javaw.exe 只是同一 JVM 的不同启动器(仅运行时)。不同的java编译器是javac.exe和ecj(java的eclipse编译器)
标签: java generics inheritance jls method-hiding