Search code examples
javagenericsoverridingtype-erasure

How these strange override rules with erasure can be explained?


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

Solution

  • 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.