Bug ID: JDK-6260652 (coll) Arrays.asList(x).toArray().getClass() should be Object[].class
问题主要是下面这么一段c.toArray might (incorrectly) not return Object[] (see 6260652)
翻译过来的话就是toArray返回的数组的类型不一定是Object[]的
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
我们看bug库的标题是JDK-6260652 : (coll) Arrays.asList(x).toArray().getClass() should be Object[].class
可是我们看下面这一段代码
public static void test1(){
List<String> list = new java.util.ArrayList<String>(Arrays.asList("123"));
//class java.util.ArrayList
Object[] listArray = list.toArray();
System.out.println(listArray.getClass());//class [Ljava.lang.Object;
listArray[0] = new Object();
}
public static void test2(){
List<String> list = Arrays.asList("123");// class java.util.Arrays$ArrayList
Object[] objArray = list.toArray();
System.out.println(objArray.getClass()); // class [Ljava.lang.String;
objArray[0] = new Object(); // cause ArrayStoreException
}
test2()的list.toArray().getClass()却不是Obeject[].class了
接下来我们来看一下toAarry的实现
Arrays$ArrayList toArray的实现
public Object[] toArray() {
return (Object[])this.a.clone();
}
ArrayList toArray的实现
public Object[] toArray() {
return Arrays.copyOf(this.elementData, this.size);
}
这里看没问题呀,返回的类型都是Object[],可是getClass的结果为什么会出现差异。
其实原因是:toArray 方法返回的是 Object[],但是与 java.util.ArrayList 不同的是这里底层存储是泛型类型的数组private final E[] a,所以保留了实际的类型。
public static void test() {
Object[] objs = new String[1]; //Arrays$ArrayList toArray的实现类型这个过程
System.out.println( objs.getClass() ); //class [Ljava.lang.String;
Object[] objs2 = new Object[1];//ArrayList toArray的实现类型这个过程
objs2[0] = new String();
System.out.println( objs2.getClass() ); //class [Ljava.lang.Object;
}
这样看更加直观
#Array.toList()实现#
public static void test4(){
String[] strings = {new String(),new String()}; //private final E[] a
Object[] objects = (Object[]) strings.clone(); //return (Object[])this.a.clone();
System.out.println(objects.getClass()); //class [Ljava.lang.String;
}