public ArrayList(Collection<? extends E> c) {elementData = c.toArray();size = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class);}
c.toArray might not return Object[] 不明白toArray为何会不返回object[],有没有其他例子说明下呢?stackoverflow有这个问题,不过回答貌似也没有启发的感觉,是我智商捉急了么- -||http://stackoverflow.com/questions/8521147/why-need-to-convert-type-to-object-array-in-arraylists-construction
解决方案
List<Object> l = new ArrayList<Object>(Arrays.asList("foo", "bar"));// Arrays.asList("foo", "bar").toArray() produces String[], // and l is backed by that arrayl.set(0, new Object()); // Causes ArrayStoreException, because you cannot put // arbitrary Object into String[]
stackoverflow上这个回答是只在toArray()的时候,返回的是String[]类型,如果ArrayList的构造函数中没有那部分类型检查的代码,会导致其elementData的实际类型是String[],而不是Object[],所以当你将其中一个元素更换为Object元素时会报错,你可以试下如下代码,肯定会报ArrayStoreException的错误。
Object[] arr = new String[]{"a","b"};arr[0]=new Object();
代码二等同于代码一ArrayList构造函数中没有类型检查。
当然根本原因就是java强类型检查的问题了
toArray源码,在ArrayList.java中
public Object[] toArray() { return Arrays.copyOf(elementData, size); } // Arrays.copyOf sourceCode public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); }
注意copyOf实际用的是泛型,虽然返回的是Object[],但实际元素已经声明为String[]了。