Java 重写泛型方法
根据(Java语言规范): 子签名的概念旨在表示两个方法之间的关系,这两个方法的签名不完全相同,但其中一个方法可以覆盖另一个方法。具体来说,它允许签名不使用泛型类型的方法重写该方法的任何泛型版本 此代码基于JLS示例:Java 重写泛型方法,java,generics,overriding,Java,Generics,Overriding,根据(Java语言规范): 子签名的概念旨在表示两个方法之间的关系,这两个方法的签名不完全相同,但其中一个方法可以覆盖另一个方法。具体来说,它允许签名不使用泛型类型的方法重写该方法的任何泛型版本 此代码基于JLS示例: interface CollectionConverter<U> { <T> List<T> toList(Collection<T> c); void fooMethod(Class<?> c);
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;
}
}
接口采集转换器{
收费表(c组);
无效方法(c类);
可比方法3(E);
可比方法4(U);
}
类重写器实现CollectionConverter{
@凌驾
公众名单收费表(c组){
返回null;
}
@凌驾
公共方法(c类){
}
@凌驾
公共可比方法3(对象o){
返回null;
}
@凌驾
//编译错误,必须将对象更改为整数
公共可比方法4(对象u){
返回null;
}
}
根据JLS,我理解为什么前三种方法工作得很好,但我不明白为什么method4
有这种编译错误:
类型重写器的方法method4(对象)必须重写或实现超类型方法
因为在接口中,method4是使用与接口(U)相同的类型参数声明的。如果你把它换成别的东西,它应该能工作 比如说
<A> Comparable<A> method4(A a);
可比方法4(A);
问题在于类型变量U
在该点绑定到整数。如果您将声明更改为
public Comparable method4(Integer u) ...
它是一个覆盖在采集转换器
中方法4
的签名是
Comparable<U> method4(U u);
您可以在重写器中声明method4(Object u)
,但该方法签名不会重写接口中指定的method4(Integer u)
,就像您根本不使用泛型一样。对于希望使用泛型参数重写方法的特定情况,它并没有泛型返回类型,您需要确保param的类型实际上是该泛型类型的子类型
例如:
protected Response updateResource(long id, T payload, RequestContext context){}
被
@Override
protected Response updateResource(long id, Payload payload, RequestContext context){}
竖起拇指查看IntelliJ IDEA的代码>生成…>重写方法…但是,在类型擦除之后,所有类型参数都将替换为对象或“扩展”列表中的第一个绑定。就像前三个方法一样,擦除后前三个方法的签名与重写器类中的签名完全相同。根据这条线索,method4的签名和返回类型应该是:Comparable method4(Object u),它与Overrider中的相同。所以,这是我的question@RobyYan-泛型不仅仅是从最小上界向下转换的语法糖。类型擦除在编译器检查类型安全性后开始。泛型的全部思想是使编译器能够为您执行类型检查。强迫编译器进行分析,就好像已经应用了类型擦除一样,这是没有希望的;泛型的全部思想是让编译器为您进行类型检查。强迫编译器进行分析,就好像已经应用了类型擦除一样,这是没有希望的;它几乎没有什么可以处理的了。“明白了,我几乎忘记了泛型的最初用途,谢谢你的回答,你只是展示了如何使用IDE方法,但你不能强迫使用Intellij。
@Override
protected Response updateResource(long id, Payload payload, RequestContext context){}