What is happening here and how to understand it?
class C<T> {
public T id(T x) {
return null;
}
}
class D extends C<String> {
public Integer id(Integer x) { // compiles! but T shall be String ???
return 7;
}
}
public static void main(String[] args) {
System.out.println(new D().id("7")); // null
System.out.println(new D().id(7)); // 7
}
By the way if I declare D like this, compilation fails with Name clash: The method id(Object) of type D has the same erasure as id(T) of type C<T> but does not override it:
class D extends C<String> {
public Object id(Object x) { // compile error !
return 7;
}
}
Use @Override annotation to check if the method really overrides another method.
In the first case you will have 2 methods, one that expect String and another that expect Integer.
In the second case you created the same method that already exits after type erasure of supertype.