请考虑以下示例:
public class Learn {
public static <T> T test (T a, T b) {
System.out.println(a.getClass().getSimpleName());
System.out.println(b.getClass().getSimpleName());
b = a;
return a;
}
public static void main (String[] args) {
test("", new ArrayList<Integer>());
}
}
Run Code Online (Sandbox Code Playgroud)
在main方法中,我test用一个String和一个ArrayList <Integer>对象调用.这两个是不同的东西,并指派ArrayList至String(一般)给出编译错误.
String aString = new ArrayList <Integer> (); // won't compile
Run Code Online (Sandbox Code Playgroud)
但我在第3行正是这样做,test程序编译并运行正常.首先,我认为,类型参数T是由一个类型,是既兼容替代String和ArrayList(像Serializable).但是println里面的两个语句分别test打印出"String"和"ArrayList"作为类型a和b.我的问题是,如果a是String和b是ArrayList在运行时,我们如何能分配a到b.
rge*_*man 10
对于一个普通的方法,Java编译器会推断出最具体的常见类型为这两个参数a和b.
推理算法确定参数的类型,如果可用,还确定分配或返回结果的类型.最后,推理算法试图找到适用于所有参数的最具体类型.
您没有将调用结果分配test给任何内容,因此没有目标来影响推理.
在这种情况下,甚至String并且ArrayList<Integer>具有共同的超类型,Serializable因此T推断为Serializable,并且您始终可以将一个相同类型的变量分配给另一个.对于其他示例,您甚至可以找到Object常见的超类型.
但只是因为你有T推断类型的变量Serializable,对象本身仍然是a String和a ArrayList,所以获取他们的类和打印他们的名字仍然打印String和ArrayList.你没有打印变量的类型; 你正在打印对象的类型.