覆盖泛型方法

4
根据Java语言规范(JLS)
子签名的概念旨在表达两个方法之间的关系,它们的签名不完全相同,但其中一个可以覆盖另一个。具体而言,它允许一个签名不使用泛型类型的方法来覆盖该方法的任何泛型版本。
此代码基于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)必须覆盖或实现一个超类型方法。

4个回答

4
< p > CollectionConvertermethod4 的签名是

Comparable<U> method4(U u);

您需要声明Overrider来实现CollectionConverter<Integer>,从而将类型参数U绑定到Integer。此时的签名为:
Comparable<Integer> method4(Integer u);

Overrider中声明method4(Object u)是可以的,但这个方法签名不再像你没有使用泛型那样覆盖接口中指定的method4(Integer u)


然而,在类型擦除之后,所有类型参数都被替换为Object或“extends”列表中的第一个限定符。就像前三种方法一样,在擦除之后,前三种方法的签名与Overrider类中的签名完全相同。按照这个思路,method4的签名和返回类型应该是:Comparable method4(Object u),这与Overrider中的方法相同。所以,这是我的问题。 - Yan Yan
@RobyYan - 泛型不仅是从最小上界强制转换的语法糖。类型擦除在编译器检查类型安全性之后生效。泛型的整个理念就是让编译器为您执行类型检查。强制编译器进行分析,好像已经应用了类型擦除,这是毫无希望的; 它几乎没有剩余的工作内容。 - Ted Hopp
泛型的整个理念是让编译器为您执行类型检查。强制编译器像已经应用了类型擦除一样进行分析是没有意义的;几乎没有什么东西可以供它使用。明白了,我差点忘记了泛型的原始目的,感谢您的回答。 - Yan Yan

2
问题在于类型变量 U 在那个时候被绑定为 Integer。如果你将声明改为:
public Comparable method4(Integer u) ...

它是一个覆盖(override)。


1

因为在接口中,method4使用了与接口相同的类型参数(U)。如果将其更改为其他内容,则应该可以正常工作。

例如

<A> Comparable<A> method4(A a);

0

对于想要使用泛型参数覆盖方法的特定情况,该方法没有泛型返回类型,您需要确保参数的类型实际上是该泛型类型的子类。

例如:

protected Response updateResource(long id, T payload, RequestContext context){}

被覆盖

@Override
protected Response updateResource(long id, Payload payload, RequestContext context){}

赞 IntelliJ IDEA 的 Code > Generate... > Override Methods...


你只是展示如何生成覆盖方法,但不能强制使用Intellij。 - Kaushik Burkule

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接