bug库链接
问题主要是下面这么一段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 ) {
if (elementData.getClass() != Object[].class )
elementData = Arrays.copyOf(elementData, size, Object[].class );
} else {
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" ));
Object[] listArray = list.toArray();
System.out .println(listArray.getClass());
listArray[0 ] = new Object();
}
public static void test2 (){
List<String> list = Arrays.asList("123" );
Object[] objArray = list.toArray();
System.out .println(objArray.getClass());
objArray[0 ] = new Object();
}
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 ];
System.out .println( objs.getClass() );
Object[] objs2 = new Object[1 ];
objs2[0 ] = new String();
System.out .println( objs2.getClass() );
}
这样看更加直观
#Array.toList()实现#
public static void test4 (){
String[] strings = {new String(),new String()};
Object[] objects = (Object[]) strings.clone();
System.out .println(objects.getClass());
}