简体   繁体   中英

Java method polymorphism when casting parameter to generic variable

Given the following class

public class Test<T extends Test.UpperClass> {

    public static class BottomClass {}
    public static class UpperClass extends BottomClass {}
    public void method(BottomClass c) {
        System.out.println("BottomClass " + c.getClass());
    }
    public void method(T c) {
        System.out.println("UpperClass " + c.getClass());
    }
    public void test() {
        method(new UpperClass());
    }
    public static void main(String[] args) {
        new Test<UpperClass>().method(new UpperClass()); // calls method(T)
        new Test<UpperClass>().test(); // calls method(BottomClass)
    }
}

The code above if executed, will print out UpperClass class Test$UpperClass and BottomClass class Test$UpperClass , which is not what I expected as T extends UpperClass , I would expect both will call method(T) as the erasure of T is UpperClass . Why method(BottomClass) is called instead?

Let's simplify:

public class Foo<T> {
    void method(T t) {}

    void test() {
        method(new Object());  // compiler error: is T Object?
    }

    public static void main(String[] args) {
        new Foo<Object>().test();
        new Foo<String>().test(); // both must compile!
    }
}

The above method call doesn't compile, because the instance can't know what type T is. The fact that Object and T have the same erasure is irrelevant at compile time. Your example is a more convoluted demonstration of the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM