Reputation: 3478
Can someone tell me what is wrong with the following code?
Set<String> cmds = *a method call that returns a Set<String>*
String[] cmdarr = (String[]) cmds.toArray();
int i;
for(i=0; i<cmdarr.length;i++){
System.out.println(cmdarr[i]);
It gave the following error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at a.jim.Test.main(Test.java:79)
Thanks in advance!
Upvotes: 1
Views: 308
Reputation: 269897
The Set
itself doesn't have any type information about its elements available at runtime; the type parameter <String>
is erased during compilation. So, the toArray()
method always creates an array of type Object[]
.
You can pass an array to the method and have the contents of the set copied into it:
String[] cmdarr = cmd.toArray(new String[cmd.size()]);
The the array you pass in is too small, a new one with the same component type will be created using reflection, but that is not as efficient as passing in one of the correct size.
Upvotes: 5
Reputation: 897
Piggybacking off of what @erickson said, the parameterized type in the Set
is simply a compile-time safety check. Once the code is compiled, Set<String>
actually becomes Set
of Objects
.
Casting is a method of achieving greater specificity at runtime. You are getting the compile-time error though because of something called "type erasure" that happens to generic types when they are compiled, as explained in the previous paragraph. Your cmdarr
reference is actually just a placeholder for an object of type String[]
. This placeholder can never point to a Object[]
just like a Set<List>
placeholder can never point to a Set<ArrayList>
.
Take a look at the walkthrough about generics in the Java Tutorials. It's a lot to wrap your head around, but invaluable when using the Collections package.
Java Tutorials: Lesson Generics
Upvotes: 0
Reputation: 94653
Try to pass the type reference.
String[] cmdarr = cmds.toArray(new String[0]);
Upvotes: 1