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;
}
}
这段代码让我疑惑的是当 elementData.getClass() != Object[].class 时为什么需要转换,然后接着找了点资料,很多都只是通过列子来说明问题,没有把造成这个问题的原因说明白
List<String> list = new ArrayList<>(Arrays.asList("list"));
System.out.println(list.getClass());//class java.util.ArrayList
Object[] listArray = list.toArray();
System.out.println(listArray.getClass());//class [Ljava.lang.Object;
listArray[0] = new Object();
List<String> asList = Arrays.asList("asList");
System.out.println(asList.getClass());//class java.util.Arrays$ArrayList
Object[] asListArray = asList.toArray();
System.out.println(asListArray.getClass());//class [Ljava.lang.String;
asListArray[0] = new Object();//! java.lang.ArrayStoreException
String[] strings = {new String()};
Object[] objects = strings;
objects[0] = new Object();//! java.lang.ArrayStoreException
最主要的原因其实是list.toArray()实现方式不一样,导致返回的数组真实类型不一样
//java.util.Arrays$ArrayList
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
//java.util.ArrayList
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}