根据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)必须覆盖或实现超类型方法。
答案 0 :(得分:4)
method4
中CollectionConverter
的签名是
Comparable<U> method4(U u);
您声明Overrider
实施CollectionConverter<Integer>
,从而将类型参数U
绑定到Integer
。然后签名变为:
Comparable<Integer> method4(Integer u);
您可以在method4(Object u)
中声明Overrider
,但该方法签名不会覆盖在界面中指定的method4(Integer u)
,如果您根本不使用泛型的话。
答案 1 :(得分:2)
问题是类型变量U
此时绑定到Integer
。如果您将声明更改为
public Comparable method4(Integer u) ...
是一个覆盖
答案 2 :(得分:1)
因为在接口中,method4声明的参数类型参数与接口(U)相同。如果你把它改成其他东西,它应该可以工作。
例如
<A> Comparable<A> method4(A a);
答案 3 :(得分:0)
对于希望用泛型参数覆盖没有泛型返回类型的方法的特定情况,您需要确保参数的类型实际上是该泛型类型的子代。
例如:
protected Response updateResource(long id, T payload, RequestContext context){}
被
覆盖@Override
protected Response updateResource(long id, Payload payload, RequestContext context){}
对IntelliJ IDEA的代码>生成...>重写方法...