让我们拥有以下代码:
public class TestGenerics {
static <T> void mix(ArrayList<T> list, T t) {
System.out.println(t.getClass().getName());
T item = list.get(0);
t = item;
System.out.println(t.getClass().getName());
}
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<Object>();
list.add(new Integer(3));
mix(list, "hello world");
}
}
在输出中我得到:
java.lang.String
java.lang.Integer
这是胡说八道 - 我们刚刚将Integer
分配给String
而没有获得ClassCastException
!我们不能这样写:
String s = new Integer(3);
但这就是我们刚刚在这里所做的。
这是一个错误还是什么?
答案 0 :(得分:9)
在list
为ArrayList<Object>
的情况下,T
被视为Object
,因此您可以将其视为:
static void mix(ArrayList<Object> list, Object t)
因此,您已将Integer
分配给Object
(之前为String
)。
Object obj = new Integer(3);
obj = "Hello"; //No CCE here
答案 1 :(得分:2)
您有一个Object列表。列表中的一个对象是String,另一个是Integer。 getClass
返回对象的 runtime 类型,而不是静态类型。这里没有涉及铸造。
答案 2 :(得分:2)
在我看来,好像getClass()
返回对象的动态(运行时)类型,而泛型只处理静态(编译时)类型信息。
您在控制台上打印的是实际的动态类型。
但是,在您的示例代码中,T
类型为Object
,因此t = item
是完全有效的分配。