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 時爲何須要轉換,而後接着找了點資料,不少都只是經過列子來講明問題,沒有把形成這個問題的緣由說明白java
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); }