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());
}