views:

75

answers:

3

Let us have the following code:

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

In the output I get:

java.lang.String
java.lang.Integer

It's nonsense - we've just assigned Integer to String without getting ClassCastException! We can't write it like that:

String s = new Integer(3);

but this is what we have just done here.

Is it a bug or something?

+9  A: 

In your case as list is an ArrayList<Object>, T is considered as an Object so you can see things as :

 static void mix(ArrayList<Object> list, Object t)

So you assigned an Integer to an Object (which was a String before).

Object obj = new Integer(3);
obj = "Hello"; //No CCE here
Colin Hebert
+2  A: 

You have a list of Object. One of the objects in the list is a String, the other is an Integer. getClass returns the runtime type of the object, not the static type. There is no casting involved here.

Mark Byers
+2  A: 

This seems to me as if getClass() returns the dynamic (runtime) type of an object, while generics deals only with static (compile-time) type information.

What you print on the console is the actual, dynamic types.

However, in your example code, T would be type Object, therefore t = item is a perfectly valid assignment.

stakx