Java为什么在编译时无法确定泛型类型的方法重载
我想知道为什么下面的代码不能使用编译时泛型类型信息来正确查找最具体的方法重载,而是始终使用适用于所有潜在泛型参数的方法。有没有办法在编译时打开泛型参数类型,以避免在运行时出现令人讨厌的反射
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class Temp {
class A<T> {
T x;
A(T x) {
this.x = x;
}
String bar = foo(x);
private String foo(Integer i) {
return "Int";
}
private String foo(String i) {
return "String";
}
private <T> String foo(List<T> l) {
return "List";
}
private <T> String foo(T v) {
return "Value";
}
}
@Test
public void IntTest() {
Assert.assertEquals(new A<Integer>(1).bar, "Int");
}
@Test
public void StringTest() {
Assert.assertEquals(new A<String>("A").bar, "String");
}
@Test
public void ListTest() {
Assert.assertEquals(new A<List<String>>(new ArrayList<String>()).bar, "List");
}
@Test
public void LongTest() {
Assert.assertEquals(new A<Long>(1L).bar, "Value");
}
}
# 1 楼答案
这是因为泛型是在编译时删除的。 有一种擦除的概念,它在编译时删除所有泛型代码,并用类型转换替换它。因此java在运行时不会意识到泛型方法
编辑:
也请检查此链接:http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotOverload
# 2 楼答案
这是因为编译器必须为
T
使用的每个类型生成不同的类A
(因为A.bar
的初始值设定项需要调用不同的方法)。决定只生成一个类。与C++不同,编译器为所有使用的类型参数生成一个新类型。p>换句话说,类型
A<String>
的编译代码与类型A<Integer>
不同,但编译后只有类型A