Reputation: 125
LinkedList<Integer> adjMatrix[] = new LinkedList[10];
Object[] temp = (Object[]) adjMatrix;
LinkedList<String> string = new LinkedList<String>();
string.add("abc");
temp[3] = string;
System.out.println(adjMatrix[3].get(0));
//prints abc
//====================================================
LinkedList<String>[] stringList = new LinkedList[10];
Object[] oa = (Object[]) stringList;
LinkedList<Integer> listInt = new LinkedList<Integer>();
listInt.add(new Integer(3));
oa[1] = listInt;
System.out.println(stringList[1].get(0));
// gives ClassCastException java.lang.Integer cannot be cast to java.lang.String
I'm kind of confused what exactly happened in the first case, an integer accepted a string value but it didn't happen in the second case. Any thoughts?
Upvotes: 1
Views: 95
Reputation: 691973
In the first case, you're just printing adjMatrix[3].get(0)
. The compiler thinks that this expression is an Integer. But the actual type doesn't matter: the generated byte-code is
37: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
So it just passes the object it got from the list to PrintStream.println(Object)
, which then calls String.value()
on this object. The compiler never adds a cast to the byte-code, because it's not necessary.
In the second case, you print stringList[1].get(0)+""
, which the compiler thinks it's a concatenation of a String with the empty String. So the generated byte-code is
101: invokevirtual #8 // Method java/util/LinkedList.get:(I)Ljava/lang/Object;
104: checkcast #14 // class java/lang/String
107: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
110: ldc #16 // String
112: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
115: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
118: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
As you see, there is a checkcast instruction here, because the bytecode needs to call StringBuilder.append(String)
, and the expression thus needs to be cast to a String. Since it's actually an Integer, it throws a ClassCastException.
Upvotes: 6
Reputation: 159135
The first example create a corrupted array. This is why you get warning when trying to use arrays of generics, because the JVM cannot enforce type safety.
Remember, because of type erasure, LinkedList<Integer> adjMatrix[]
is actually a LinkedList adjMatrix[]
at runtime, i.e. it can store all object types.
Upvotes: 2