另一个java泛型混淆

时间:2010-10-02 08:20:05

标签: java generics collections

让我们拥有以下代码:

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);

但这就是我们刚刚在这里所做的。

这是一个错误还是什么?

3 个答案:

答案 0 :(得分:9)

listArrayList<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是完全有效的分配。