Java两级泛型奇怪的行为
我有以下逻辑Java两级泛型奇怪的行为,java,generics,type-parameter,Java,Generics,Type Parameter,我有以下逻辑 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> { Te
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不应该知道Gentest的实际类吗?方法重载解析发生在编译时 当编译器编译Gen时,它对E一无所知,也就是说,它不能保证E扩展了A,因此它必须用调用test重载 如果删除该测试重载,将出现编译错误,因为另一个测试根本不兼容: 类型测试中testE扩展A的方法不适用于参数E
要使其调用另一个,请更改为Gen.方法重载解析在编译时发生 当编译器编译Gen时,它对E一无所知,也就是说,它不能保证E扩展了A,因此它必须用调用test重载 如果删除该测试重载,将出现编译错误,因为另一个测试根本不兼容: 类型测试中testE扩展A的方法不适用于参数E
要让它调用另一个,请更改为Gen.这不是很明显吗?当您通过mnew B代时会发生什么。让我知道调用了哪个方法。在public void me e{test.teste;}e来自类Gen,但在那一点上它是未知的,所以编译器必须选择方法签名,它将匹配可以分配给e的任何类型,这里是public void teste{..}而不是public void teste{..}。如果您想让编译器知道E可能只接受A的子类,这样它就可以由public void testE处理。E{..}将它声明为类Gen{..}。对于Gen.mnew B,它返回的结果是相同的。这不是很明显吗?当您通过mnew B代时会发生什么。让我知道调用了哪个方法。在public void me e{test.teste;}e来自类Gen,但在那一点上它是未知的,所以编译器必须选择方法签名,它将匹配可以分配给e的任何类型,这里是public void teste{..}而不是public void teste{..}。如果您想让编译器知道,E可能只接受A的子类,这样它就可以由public void testE处理。E{..}将它声明为类Gen{..}。对于Gen.mnew B,它将返回相同的结果