1. 程式人生 > >Java中的陣列互相賦值

Java中的陣列互相賦值

    本文探討Java中陣列中的賦值問題。在探討這個問題之前必須先弄懂一件事,Java中的陣列到底是什麼東西?是類,是物件,還是什麼其他奇奇怪怪的東西。答案是:Java中的陣列本質上是物件。但是這個物件不是通過某個類例項化來的,而是JVM建立的,這也就不難解釋對於一個數組物件arr,我們可以直接通過arr.length訪問陣列的長度。

    現在我們知道了Java中陣列本質上是物件,那麼我們來看一下這樣的程式碼合理不合理:

int[] a = {1,2,3};
int[] b = new int[3];
b = a;
for(int i = 0; i < a.length; i++)
    a[i] = 0;

        我們本來的想法是把a陣列的值賦值給b,然後將a陣列清零,但是我們會發現a,b陣列都被清零了。
    既然陣列本質是物件,那麼我們來分析一下這兩句程式碼在Java記憶體模型中發生了什麼。

    int[] a = {1,2,3};的時候,堆中會生成一個對應的物件,a會指向這個物件,然後int[] b = new int[3];的時候,b也會指向這個物件。那麼比如我們在對a[0]進行修改的時候,實際上是對堆中物件做出了修改。b陣列仍然是指向這個堆中物件的,當然b陣列的值也改變了。

    說到這裡已經顯而易見了,這樣實際上不太合理,比較兩個引用都是指向同一個堆中物件,其中一個修改必然會導致另一個的修改。

    那麼陣列的賦值究竟應該怎麼做呢?

一、使用for迴圈

int[] a = {1,2,3};
int[] b = new int[3];
for(int i = 0; i<a.length; i++)
    b[i] = a[i];
    這樣可以實現賦值操作,而且靈活性不錯,但是效率是個問題。

二、使用Object的clone()

    既然陣列本質是物件,那麼他就有clone()方法。我們可以使用clone()方法進行復制:

int[] a={1,2,3};
int[] b=(int[]) a.clone();//別忘了強制型別轉換
三、使用System的靜態方法arraycopy()

    System提供了一個靜態方法arraycopy(),原型如下:

    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

    src:源陣列

    srcPos:源陣列要複製的起始位置
    dest:目的陣列

    destPos:目的陣列放置的起始位置
    length:複製的長度

    我們可以用它來進行陣列之間的複製:

int[] a ={1,2,3};
int[] b = new int[3];
System.arraycopy(a,0,b,0,3);
    這個方法效率很高,而且具有一定的靈活性。許多基於陣列實現的Java的集合類底層在陣列複製的時候都是使用這個方法。