Yan Yan
Yan Yan

Reputation: 65

Override generic method

According to the JLS (Java Language Specification):

The notion of subsignature is designed to express a relationship between two methods whose signatures are not identical, but in which one may override the other. Specifically, it allows a method whose signature does not use generic types to override any generified version of that method.

This code is based on the JLS example:

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;
    }
}

According to the JLS, I understand why the first three methods work well, but I can't figure out why method4 has this compilation error:

The method method4(Object) of type Overrider must override or implement a supertype method.

Upvotes: 4

Views: 2092

Answers (4)

Mihai Savin
Mihai Savin

Reputation: 61

For the specific case of wanting to override a method with a generic param, which does not have a generic return type, you need to make sure type of the param is actually a child of the that generic type.

For example:

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

is overriden by

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

Thumbs up for the IntelliJ IDEA's Code > Generate... > Override Methods...

Upvotes: 0

Ted Hopp
Ted Hopp

Reputation: 234857

The signature of method4 in CollectionConverter is

Comparable<U> method4(U u);

You declare Overrider to implement CollectionConverter<Integer>, thereby binding the type parameter U to Integer. The signature then becomes:

Comparable<Integer> method4(Integer u);

You can declare a method4(Object u) in Overrider, but that method signature does not override method4(Integer u) specified in the interface any more than it would if you weren't using generics at all.

Upvotes: 4

Jim Garrison
Jim Garrison

Reputation: 86774

The problem is the type variable U is bound to Integer at that point. If you change the declaration to

public Comparable method4(Integer u) ...

it is an override

Upvotes: 2

Jakub Zaverka
Jakub Zaverka

Reputation: 8874

Because in the interface, method4 is declared with the same type parameter as the interface (U). If you change it to something else, it should work.

For example

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

Upvotes: 1

Related Questions