Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics - erasure concept

I have some code as follows:

public class java_generic {

    public static void main(String[] args) {

        T t = new X();
        t.<Object>m(new Object());
        t.<String>m(new String());

    }

    static class T {
        <E> void m (E e){
            System.out.println("here is T");
        }
    }

    static class X extends T {
        void m (String o){
            System.out.println("here is X");            
        }
    }

}

From my understanding, after type erasure, class T will become this:

    static class T {
        void m (Object e){
            System.out.println("here is T");
        }
    }

and m is overloaded.

As having m(Object) and m(String), I expect the result would be

here is T
here is X

However, the result is

here is T
here is T

I wonder why the result would be this.

like image 388
Kone Man Avatar asked Nov 22 '25 06:11

Kone Man


2 Answers

You pretty much answered your own question. You just need to fully follow the consequences. Do the erasure for all your code and you get this:

public class java_generic {

    public static void main(String[] args) {
        T t = new X();
        t.m(new Object());
        t.m(new String());
    }

    static class T {
        void m (Object e){
            System.out.println("here is T");
        }
    }

    static class X extends T {
        void m (String o){
            System.out.println("here is X");            
        }
    }
}

That hopefully makes it obvious that X.m simply does not override T.m and thus a call through a T reference can never invoke X.m.

like image 98
Sebastian Redl Avatar answered Nov 23 '25 20:11

Sebastian Redl


Since T is a superclass of X, and instance of X is assigned to superclass Object t, you can't really access subclass X methods. Thus both

   t.<Object>m(new Object());
   t.<String>m(new String());

invoking the superclass generic method.

Now check this way -

public class java_generic {

    public static void main(String[] args) {
        X x = new X();
        x.<Object>m(new Object());
        x.<String>m(new String());

    }

    static class T {
        <E> void m (E e){
            System.out.println("here is T");
        }
    }

    static class X extends T {
        void m (String o){
            System.out.println("here is X");            
        }
    }

}
like image 20
shakhawat Avatar answered Nov 23 '25 19:11

shakhawat