I was trying following example:
class BaseClass {
public void methodA(Class<?> cl) {
System.out.println("Base.methodA()");
}
}
class SubClass extends BaseClass {
public void methodA(Class cl) {
System.out.println("Sub.methodA()");
}
}
public class OverrideEx {
public static void main(String[] args) {
BaseClass b = new BaseClass();
BaseClass s = new SubClass();
b.methodA(Class.class);
s.methodA(Class.class);
}
}
Output:
Base.methodA()
Sub.methodA()
But if I change over riding method argument other way around as follows:
class BaseClass {
public void methodA(Class cl) {
System.out.println("Base.methodA()");
}
}
class SubClass extends BaseClass {
public void methodA(Class<?> cl) {
System.out.println("Sub.methodA()");
}
}
public class OverrideEx {
public static void main(String[] args) {
BaseClass b = new BaseClass();
BaseClass s = new SubClass();
b.methodA(Class.class);
s.methodA(Class.class);
}
}
I get compilation error. It says “Name clash: The method methodA(Class) of type SubClass has the same erasure as methodA(Class) of type BaseClass but does not override it”.
Why is that?
The parameterized type
Class<?>is a subtype of the raw typeClass(§4.10.2).Thus for any
xthe calls.methodA(x)in the first example would also be valid if rewritten:This is not true for the second example.
Imagine
xbeing of typeClasswhich is not a subtype ofClass<?>. That callwould be illegal because the argument’s type is not a subtype of the formal parameter’s type.
This means that
methodAofSubClassdoes not overridemethodAofBaseClass.