ragingcorgi
ragingcorgi

Reputation: 3478

Java - Casting a set

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

Answers (3)

erickson
erickson

Reputation: 269897

The Setitself 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

Zach
Zach

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

KV Prajapati
KV Prajapati

Reputation: 94653

Try to pass the type reference.

String[] cmdarr = cmds.toArray(new String[0]);

Upvotes: 1

Related Questions