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.