System.arraycopy方法的簡短總結

API使用場景

在JDK研發團隊的開發過程當中,對集合的操做過程當中常會使用到此方法。c++

API參數

public static native void arraycopy(
       Object src,  //源數組
       int srcPos,  //源數組的讀取起始位置
       Object dest, //目標數組
       int destPos, //目標數據中的寫入起始位置
       int length   //要複製的數組元素的數量
       );

Functions

  1. 將指定源數組的數組從指定位置複製到目標數組的指定位置。數組組件的子序列由src引用的源數組複製到dest引用的目標數組。複製的組件數等於length。源序列中從srcPos到srcPos+length-1的序列複製到目標序列的destPos到destPos+length-1位置。
  2. 若是src和dest參數引用的是相同的數組對象,則首先把源數組srcPos到srcPos+length-1的組件複製到具備與此相同長度的臨時數組裏,而後再把臨時數組的內容複製到目標數組destPos到destPos+length-1位置。
  3. 若是dest爲null,則拋出NullPointerException;若是src爲空,則拋出NullPointerException,而且不修改目標數組。
  4. 拋出ArrayStoreException的狀況(前7種狀況不會修改dest):
    1)src參數指向的不是數組對象
    2)dest參數指向的不是數組對象
    3)src參數和dest參數指向的對象類型不是同一種基本類型的數組
    4)src參數指向由原始組件類型組成的數組,dest參數指向由引用組件類型組成的數組
    5)dest參數指向由原始組件類型組成的數組,src參數指向由引用組件類型組成的數組
    6)srcPos+length>src.length
    7)destPos+length>dest.length
    8)對於任意i知足:srcPos <= i <= (srcPos+length-1),src.get(i)沒法轉換爲dest的成員類型。(這種狀況下,令k爲小於length的非負整數,假設此時使src[srcPos+k]不能轉換爲目標數組的成員類型,當拋異常時srcPos到srcPos+k-1的源數組成員已經經過destPos+k-1被複制到目標數組的destPos位置,目標數組的剩餘位置不會被修改。這種狀況僅適用於兩個數組都具備引用類型的成員類型的狀況)

方法特性

一、總的來講,複製方式屬於淺複製數組

  • 複製的過程只是引用變量的二次傳遞。
  • 一維數組的複製:屬性值傳遞,修改則不會影響副本
  • 二維數組的複製:複製的是第一維的引用列表,副本和原數組的指向是相同的堆地址,這個時候,值變更的影響是雙向的

二、此方法不是線程安全的,必要時要加鎖限制。
三、相比for遍歷複製,此方法更加高效。安全

  • 緣由很簡單,該方法使用內存塊總體讀取與複製,相比for的遍歷尋址來講天然會快,不過這個速度優點在數組成員比較多的時候纔會有較明顯的體現。下面貼出native方法中關鍵部分copy的方法c++代碼:
void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
    if (from > to) {
      jint *end = from + count;
      while (from < end)
        *(to++) = *(from++);
    }
    else if (from < to) {
      jint *end = from;
      from += count - 1;
      to   += count - 1;
      while (from >= end)
        *(to--) = *(from--);
    }
}
相關文章
相關標籤/搜索