I came across something very basic but extremely bewildering today. I needed to convert a list to an array. The list contained String
instances. Perfect example of using List.toArray(T[])
, since I wanted a String[]
instance. It would not work, however, without explicitly casting the result to String[]
.
As a test scenario, I used the following code:
import java.util.Arrays; import java.util.List; public class MainClass { public static void main(String args[]) { List l = Arrays.asList("a", "b", "c"); String stuff[] = l.toArray(new String[0]); System.err.println(Arrays.asList(stuff)); } }
which does not compile. It's nearly an exact copy of the example in the javadoc, yet the compiler says the following:
MainClass.java:7: incompatible types found : java.lang.Object[] required: java.lang.String[] String stuff[] = l.toArray(new String[0]); ^
If I add a cast to String[]
it will compile AND run perfectly. But that is not what I expect when I looked at the signature of the toArray method:
<T> T[] toArray(T[] a)
This tells me that I shouldn't have to cast. What is going on?
Edit:
Curiously, if I change the list declaration to:
List<?> l = Arrays.asList("a", "b", "c");
it also works. Or List<Object>
. So it doesn't have to be a List<String>
as was suggested. I am beginning to think that using the raw List
type also changes how generic methods inside that class work.
Second edit:
I think I get it now. What Tom Hawtin wrote in a comment below seems to be the best explanation. If you use a generic type in the raw way, all generics information from that instance will be erased by the compiler.
you forgot to specify the type parameter for your List:
List<String> l = Arrays.asList("a", "b", "c");
in this case you can write safety:
String[] a = l.toArray(new String[0]);
without any cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With