覆盖泛型方法

时间:2012-03-16 03:47:47

标签: java generics override

根据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)必须覆盖或实现超类型方法。

4 个答案:

答案 0 :(得分:4)

method4CollectionConverter的签名是

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的代码>生成...>重写方法...