I have the following logic
public class Why {
public static void main(String[] args) {
Gen<A> gen = new Gen<>();
gen.m(new A()); //eeeeeeeeee A
}
}
class A {}
class B extends A {}
class C extends A {}
class Gen<E> {
Test test = new Test();
public void m(E e) {
test.test(e);
}
}
class Test {
public <E extends A> void test(E e) {
System.out.println("XXXXXXXXXX " + e.getClass().getSimpleName());
}
public <E> void test(E e) {
System.out.println("eeeeeeeeee " + e.getClass().getSimpleName());
}
}
the output for main means the compiler picks the second method in Test, is it strange or I missed something? shouldn'd java know the actual class for Gen#test?
Method overload resolution happens at compile-time.
When the compiler is compiling Gen<E>
, it doesn't know anything about E
, i.e. it cannot guarantee that E
extends A
, so it has to call the overload of test
with <E>
.
If you remove that overload of test()
, you'll get a compile error, since the other one is not compatible at all:
The method test(E extends A) in the type Test is not applicable for the arguments (E)
To make it call the other one, change to Gen<E extends A>
.