根据the JLS(Java语言规范):
子签名的概念旨在表达两种方法之间的关系,这两种方法的签名不相同,但可以覆盖另一种方法。具体来说,它允许其签名不使用泛型类型的方法覆盖该方法的任何泛化版本。
此代码基于JLS示例:
interface CollectionConverter<U> {
<T> List<T> toList(Collection<T> c);
void fooMethod(Class<?> c);
<E>Comparable<E> method3(E e);
Comparable<U> method4(U u);
}
class Overrider implements CollectionConverter<Integer> {
@Override
public List toList(Collection c) {
return null;
}
@Override
public void fooMethod(Class c) {
}
@Override
public Comparable method3(Object o) {
return null;
}
@Override
// compile error, have to change Object to Integer
public Comparable method4(Object u) {
return null;
}
}
根据JLS,我理解为什么前三种方法运行良好,但我无法弄清楚为什么method4
有这个编译错误:
Overrider类型的方法method4(Object)必须覆盖或实现超类型方法。
在method4
的CollectionConverter
的签名是
Comparable<U> method4(U u);
你声明Overrider
来实现CollectionConverter<Integer>
,从而将类型参数U
绑定到Integer
。然后签名变为:
Comparable<Integer> method4(Integer u);
您可以在method4(Object u)
中声明Overrider
,但该方法签名不会覆盖界面中指定的method4(Integer u)
,如果您根本不使用泛型的话。
问题是类型变量U
在那时被绑定到Integer
。如果您将声明更改为
public Comparable method4(Integer u) ...
它是一个覆盖
因为在接口中,method4声明与接口(U)具有相同的类型参数。如果您将其更改为其他内容,则应该可以正常工作。
例如
<A> Comparable<A> method4(A a);