Java 二级泛型的奇怪行为
Java two level generics strange behaviour
我有以下逻辑
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());
}
}
main 的输出意味着编译器在测试中选择了第二个方法,这很奇怪还是我错过了什么? java 不应该知道 Gen#test 的实际 class 吗?
方法重载解析发生在编译时。
当编译器编译Gen<E>
时,它对E
一无所知,即它不能保证E
扩展A
,所以它必须用 <E>
.
调用 test
的重载
如果删除 test()
的重载,则会出现编译错误,因为另一个根本不兼容:
The method test(E extends A) in the type Test is not applicable for the arguments (E)
要使其调用另一个,请更改为 Gen<E extends A>
。
我有以下逻辑
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());
}
}
main 的输出意味着编译器在测试中选择了第二个方法,这很奇怪还是我错过了什么? java 不应该知道 Gen#test 的实际 class 吗?
方法重载解析发生在编译时。
当编译器编译Gen<E>
时,它对E
一无所知,即它不能保证E
扩展A
,所以它必须用 <E>
.
test
的重载
如果删除 test()
的重载,则会出现编译错误,因为另一个根本不兼容:
The method test(E extends A) in the type Test is not applicable for the arguments (E)
要使其调用另一个,请更改为 Gen<E extends A>
。