user3706408
user3706408

Reputation: 41

Java generic method overriding

abstract class A {
    abstract public void dosome(Class<? extends Number> c);
}

class B extends A {
    @Override
    public void dosome(Class<Number> c) {}
}

From Java docs: An instance method m1, declared in class C, overrides another instance method m2, declared in class A iff all of the following are true: ..... The signature of m1 is a subsignature (§8.4.2) of the signature of m2.

The signature of a method m1 is a subsignature of the signature of a method m2 if either: the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

Is erasure of A

dosome(Class<Number> c)?

If so what is wrong?

EDIT1: Or if I switch generic type:

abstract class A {
    abstract public void dosome(Class<Number> c);
}

class B extends A {
    @Override
    public void dosome(Class<? extends Number> c) {}
}

What is wrong in this case?

EDIT2: I know how to fix it, but I want to understand, what is wrong in this case according java rules.

Upvotes: 1

Views: 177

Answers (2)

Sajan Chandran
Sajan Chandran

Reputation: 11487

The method dosome in the abstract class, the caller has the option to invoke any type of class as long it a sometype of Number

abstract public void dosome(Class<? extends Number> c);

But you overridden the method like

public void dosome(Class<Number> c) {}

which will prevent the user from invoking any type of Number, meaning you cannot invoke with integer type.

By the rules of overriding, you cannot change the method parameters. So,

Class<? extends Number> and Class<Number> are not the same, its two different type of parameter and that's why its a compiler error.

Upvotes: 1

Smutje
Smutje

Reputation: 18123

If you want to be able to define the concrete argument type in the subclasses depending on a common base type every argument type has to extend, you have to write something like

abstract class A<T extends Number> {
    abstract public void dosome(Class<T> c);
}

class B extends A<Number> {
    @Override
    public void dosome(Class<Number> c) {}
}

The problem with your code is the special meaning of ? extends Number describing an "unknown" type with a given "upper bound" which can be used when you don't care or don't be able to obtain the concrete type.

Upvotes: 1

Related Questions