Java 泛型 - 擦除概念

Java generics - erasure concept

我有一些代码如下:

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

}

根据我的理解,在类型擦除之后,class T 会变成这样:

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

并且 m 超载了。

由于有 m(Object)m(String),我希望结果是

here is T
here is X

然而,结果是

here is T
here is T

不知道为什么会是这样

你几乎回答了你自己的问题。你只需要完全遵守后果。擦除 all 你的代码,你会得到这个:

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

这有希望表明 X.m 根本不会覆盖 T.m,因此通过 T 引用的调用永远不会调用 X.m.

因为 TX 的超类,并且 X 的实例被分配给超类对象 t,你不能真正访问子类 X 方法。因此

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

正在调用超类泛型方法。

现在这样检查 -

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

}