Java 非泛型方法隐藏具有交集类型的泛型方法



如果三个公共接口定义为:

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 的超类和超接口中,否则 C 中的代码可以访问 (§6.6(。

其中子签名在 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(吗?

">...有人可以解释为什么Subber的方法不能编译......">

实现了您列出的代码;逐字逐句。我的Main.main(String[])通过调用Subber.hmm(null)Subber.hmm(One)编译得很好.

我唯一不同的是引入了一个新的Four接口,满足<E extends One & Two & Three> void Super.hmm(E)类型参数部分的要求。

然后,我将一个Four实例传递到Subber.hmm(One)中,以确认Super.hmm(E)没有被调用;证明它实际上是隐藏的。

">...引用可靠的来源(最好是JLS(?...">

该实现的行为与您引用的 JLS 规范所描述的完全一样。

E的类型仍未定义,您可以通过为 Super 类设置 E 泛型并在 Subber 类中定义它来参数化它:

public class Super<E> {
public static <E extends One & Two & Three> void hmm(E item) {}
}
public class Subber extends Super<One> {
public static void hmm(One item) {}
}

最新更新