首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

List.toArray() 陷阱解析:避免 ClassCastException 的正確姿勢

     編輯:Java 相關知識

常見錯誤現場

List list = new ArrayList();
list.add(new Long(1));

// ❌ 錯誤:拋出 ClassCastException
Long[] arr = (Long[]) list.toArray(); 

原因:無參 toArray() 返回 Object[],無法強轉為 Long[],因陣列型別在運行時具體化,Object[] 不是 Long[] 的子型別。

正確用法:傳入型別化陣列

// ✅ 正確:傳入目標型別陣列(長度建議 = list.size())
Long[] arr = list.toArray(new Long[list.size()]);

JDK 內部會:

  1. 若傳入陣列長度 ≥ size,直接填入並返回該陣列。
  2. 若長度 < size,反射創建新陣列(型別同傳入陣列)並填入。

注意事項

  • 多餘元素為 null:若傳入陣列長度 > size,多出位置填充 null,使用時需檢查。
  • 零長度陣列優化:new Long[0] 同樣可行,JDK 會自動創建適當大小新陣列,甚至可能利用緩存提升效能(JDK 6+)。
  • 泛型協助:Java 5+ 建議使用 List<Long>,編譯器會提示型別不匹配。

完整範例

import java.util.*;

public class ToArrayDemo {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(1L);
        list.add(2L);
        list.add(3L);

        // 方式一:零長度陣列(推薦)
        Long[] arr1 = list.toArray(new Long[0]);
        System.out.println(Arrays.toString(arr1)); // [1, 2, 3]

        // 方式二:精確長度
        Long[] arr2 = list.toArray(new Long[list.size()]);
        System.out.println(Arrays.toString(arr2));

        // 方式三:較大陣列(尾部補 null)
        Long[] arr3 = list.toArray(new Long[5]);
        System.out.println(Arrays.toString(arr3)); // [1, 2, 3, null, null]
    }
}

原理深度剖析(JDK 源碼片段)

// ArrayList.toArray(T[] a)
public  T[] toArray(T[] a) {
    if (a.length < size)
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

關鍵點:a.getClass() 獲取運行時陣列型別(如 Long[]),Arrays.copyOf 据此創建同型別新陣列,保證型別安全。

總結

List.toArray() 看似簡單,實則藏著型別擦除與陣列協變的坑。牢記「傳入目標型別陣列」原則,優先使用 new T[0] 或 new T[list.size()],即可避開 ClassCastException,寫出健壯代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved