1、背景
在筆者研究 JDK 源碼時,注意到在CopyOnWriteArrayList 和ArrayList 的構造器中都出現了如下 bug 字樣
6260652 其實代表的JDK bug 列表中的編號
- http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652
- http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6515694
上面兩個 bug 其實是同一個問題。那他到底意味着什么呢,JDK 居然將此 bug 留在 8 了還沒處理?
看幾個例子:
2、案例
2.1 案例一
package com.javaedge; public class Test { public static void main(String[] args) { Child[] childArray = {new Child(), new Child()}; System.out.println(childArray.getClass()); Father[] fatherArray = childArray; System.out.println(fatherArray.getClass()); // ArrayStoreException fatherArray[0] = new Father(); } }
父類數組中每一個元素都是子類對象,所以如下所示,這種向上轉型不會報錯
允許子類數組轉換成父類數組。
但數組中元素類型都是Child型,所以如下所示,會報錯!!!
java.lang.ArrayStoreException
表明已經嘗試作出了錯誤類型的對象存儲到對象的數組。
例如,下面的代碼生成一個ArrayStoreException
這意味着Object[]數組,並不表示可以隨便將一個Object對象放進去,而取決於數組中元素的實際類型。
2.2 案例二
List<String> list = Arrays.asList("JavaEdge"); // 返回的類型是java.util.Arrays$ArrayList,而不是ArrayList
Object[] objects = list.toArray(); // 返回String[]數組
所以我們不能將Object對象,放到objects數組。
2.3 案例三
ArrayList的toArray()返回Object[]數組,所以可將任意對象存入 list2Array 數組。
3、總結
通過案例二和三可以得出結論:
對於
List<String> stringList
當調用
Object[] objectArray = stringList.toArray()
objectArray 實際上並不一定是Object[]類型,也就不能隨便放進一個對象。
所以開頭中的源碼都有注釋說明:
c.toArray might (incorrectly) not return Object[] (see 6260652)。
通過if判斷,避免錯誤的數組類型存儲異常。
Arrays.copyOf(elementData, size, Object[].class)
即可確保創建得到Object[]數組,因此可以存任意類型對象。