使用System.arraycopy()容易忽略的問題


arraycopy()方法在JDK中是這樣介紹的:

void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array.
A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest.
The number of components copied is equal to the length argument. The components at positions srcPos through srcPos+length-1 in
the source array are copied into positions destPos through destPos+length-1, respectively, of the destination array.
If the src and dest arguments refer to the same array object, then the copying is performed as if the components
at positions srcPos through srcPos+length-1 were first copied to a temporary array with length components
and then the contents of the temporary array were copied into positions destPos through destPos+length-1 of the destination array.

下面簡單介紹一下:

參數:
src:源數組;	srcPos:源數組要復制的起始位置;
dest:目的數組;	destPos:目的數組放置的起始位置;	length:復制的長度。

簡單描述就是從src的srcPos位置拷貝length長度的數據到dest的destPos位置,如果src和dest是同一個對象的話,則相當於先將數據拷貝到一個臨時的數組,然后再覆蓋數組中destPos開始的一段數據。

常見的使用方法:

int[] is = new int[]{1,2,3,4,5}; 
int[] is2 = new int[is.length];
System.arraycopy(is, 0, is2, 0, is.length);
System.out.println(Arrays.toString(is2));

 

但是,使用此方法有個很嚴重的問題,由於它的復制是淺復制(shallow copy),復制后的數組與原數組中的數據指向同一個位置.

示例如下:

public class Clone2 {
    public static void main(String[] args) {
        Te[] t1 = new Te[1];
        t1[0] = new Te("a");
        Te[] t2 = new Te[1];
        System.out.println(t1[0]);
        //調用
        System.arraycopy(t1, 0, t2, 0, 1);
        System.out.println(t2[0]);
    }
}
class Te{
    String name;
    Te(String name) {
        this.name = name;
    }
}
//輸出
/*
CloneTest.Te@74a14482
CloneTest.Te@74a14482
*/

從上面的輸出可以看出復制后的數組中的元素與原來指向了一個位置,這樣子很容易引發嚴重的問題.一旦我們更改了原來的數據,復制后的數據也會隨之改變.

例如:

public class Clone2 {
    public static void main(String[] args) {
        Te[] t1 = new Te[1];
        t1[0] = new Te("a");
        Te[] t2 = new Te[1];
        System.out.println("t1修改前:"+t1[0]);
        //修改t1[0]
        t1[0].name = "2";
        System.out.println("t1修改后:"+t1[0]);
        //調用
        System.arraycopy(t1, 0, t2, 0, 1);
        System.out.println("t2:"+t2[0]);
    }
}
class Te{
    String name;
    Te(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Te{" +
                "name='" + name + '\'' +
                '}';
    }
}
//輸出:
/*
t1修改前:Te{name='a'}
t1修改后:Te{name='2'}
t2:Te{name='2'}
 */
對t1[0]進行修改,但是由於t1[0]和t2[0]引用了同一個對象,因此后者也會隨之改變,在平時的使用中如果不注意的話會引起相當大的問題。
 
而且由於System.arraycoppy()是JDK中的native方法,JDK中有關於集合,數組操作的基本上都調用此方法,因此在使用這些的時候要注意。
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM