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

Java 泛型底層源碼解析:ArrayList 擴容機制與類型擦除

     編輯:Java 相關知識

ArrayList 核心源碼解析 (JDK 1.8)

1. 底層存儲結構


transient Object[] elementData; // 非私有,便於內部類訪問
  • 存儲的是對象引用,而非對象本身。
  • 默認無參構造器創建長度為 10 的 Object[]。

2. 擴容策略演進

版本擴容公式特點
JDK 1.6 及之前newCapacity = (oldCapacity * 3)/2 + 1乘法運算,增長 1.5 倍 + 1
JDK 1.7+newCapacity = oldCapacity + (oldCapacity >> 1)位移運算 (oldCapacity * 1.5),無 +1,性能更優

3. JDK 1.8 grow() 完整源碼


private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5 倍
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // 核心:複製到新數組
    elementData = Arrays.copyOf(elementData, newCapacity);
}
  • MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8(機器相關)。
  • hugeCapacity() 處理超大數組邊界情況。
  • Arrays.copyOf 內部調用 System.arraycopy(native 快速複製)。

4. 類型擦除證據

elementData 聲明為 Object[],而非 E[]。泛型 E 僅在編譯期檢查,運行期擦除為 Object。這就是為什麼不能創建泛型數組(new E[10] 非法)的原因。

工程啟示

  • 預估數據量時,使用 new ArrayList<>(initialCapacity) 避免頻繁擴容複製。
  • 大量插入前調用 ensureCapacity()。
  • 理解擦除機制,正確使用泛型通配符(? extends/? super)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved