Writing code today encountered a strange problem, the specific code is not posted, write a simplified version. As follows:
Arraylist<string> list=new arraylist<string> ();
String strings[]= (String []) List.toarray ();
So write code personally think there should be no problem, compile is no problem. But the specific operation of the time reported abnormal, as follows: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
But it's no problem to write this:
arraylist<string> list=new arraylist<string> ();
String strings[]=new string[list.size ()];
for (int i=0,j=list.size (); i<j;i++) {
Strings[i]=list.get (i);
}
For this phenomenon we can explain that: in Java, it is possible to move up and down, but the success of this transformation is based on the type of the object in the Java virtual machine. The type of each object is saved in the Java virtual machine. An array is also an object. The type of the array is [Ljava.lang.Object. convert [Ljava.lang.Object] to [ Ljava.lang.String is obviously impossible, because here is a downward transformation, and the virtual machine only holds an array of object, and there is no guarantee that the elements in the array are string, so this transformation cannot succeed. The elements inside the array are simply references to elements, not specific elements of the storage, so the type of the elements in the array is still stored in the Java Virtual machine.
Based on the above explanation, we can generalize this problem to the following model:
Object Objs[]=new object[10];
String strs[]= (string[]) Objs;
This is the same as the compilation error just above. If we modify this code, as follows:
String Strs[]=new string[10];
Object Objs[]=strs;
This way it can be compiled and passed. So we can boil down to the problem of a Java transformation rule. Let's talk about the Java array support for generics.
JDK5 has already supported the paradigm, which guarantees the security of data types in collections and maps, but the list's ToArray method returns an object [] that is confusing. Personal feeling should be able to directly return the corresponding T [] according to the paradigm. Take a closer look at the JDK source Code Discovery list is converted to an array with two methods:
Public object[] ToArray ();
This method returns all the elements in the list to an array of the same size, and all the elements in the array are of type object.
Public <T> t[] ToArray (t[] a);
This method returns all the elements in the list to an array of the same size, and all the elements in the array are of type T.
The list is so designed because the Java compiler does not allow us to type the new paradigm array. That means you can't define an array like this:
T Arr=new T[size];
But you can use t[] to represent the array, and you can force the array into t[]. For example, the list of public <T> t[] ToArray (t[] a) is implemented as follows:
Public <T> t[] ToArray (t[] a) {
if (A.length < size)
A = (t[]) Java.lang.reflect.Array.
Newinstance (A.getclass (). Getcomponenttype (), size);
System.arraycopy (elementdata, 0, a, 0, size);
if (A.length > Size)
A[size] = null;
return A;
}
As you can see from the code above, because you do not know the type of the array, you must create this array by reflection mechanism (A.getclass (). The Getcomponenttype () method is to get the type of an array element).
Finally, the list is converted to an array to handle this:
Arraylist<string> list=new arraylist<string> ();
String[] strings = new string[list.size ()];
List.toarray (strings);
Conversely, what if you want to turn the array into a list? As follows:
String[] s = {"A", "B", "C"};
List List = Java.util.Arrays.asList (s);
List conversions to arrays in Java, array to list