在Java中,對(duì)象拷貝是一個(gè)非常常見的操作,它包括假拷貝和真拷貝。我們經(jīng)常面臨這個(gè)問(wèn)題:對(duì)象引用是否真正地拷貝了對(duì)象本身或者只是拷貝了對(duì)象的引用。下文將詳細(xì)解釋這兩種情況:
假拷貝
假拷貝(shallow copy)是指在拷貝對(duì)象時(shí),只拷貝對(duì)象的引用而不是實(shí)際的對(duì)象。這意味著,如果原始對(duì)象中的一個(gè)屬性被更改了,那么所有拷貝中的該屬性都會(huì)被更改。
public class ShallowCopy { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; int[] arrCopy = arr; arrCopy[0] = 10; System.out.println(arr[0]); } }
在上面的代碼中,我們使用了假拷貝來(lái)拷貝arr數(shù)組。我們發(fā)現(xiàn),當(dāng)我們更改arrCopy中的第一個(gè)元素時(shí),原始arr數(shù)組也被改變了。因?yàn)閍rrCopy只是arr的一個(gè)引用,它們都指向同一塊內(nèi)存地址。所以,當(dāng)arrCopy更改時(shí),arr數(shù)組也會(huì)隨之更改。
真拷貝
真拷貝(deep copy)是指拷貝對(duì)象時(shí),拷貝的是對(duì)象本身而不是對(duì)象的引用。這意味著,在拷貝期間任何對(duì)原始對(duì)象的更改都不會(huì)影響拷貝,并且拷貝中對(duì)對(duì)象屬性的更改也不會(huì)影響原始對(duì)象。
public class DeepCopy { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; int[] arrCopy = new int[5]; System.arraycopy(arr, 0, arrCopy, 0, 5); arrCopy[0] = 10; System.out.println(arr[0]); } }
在上面的代碼中,我們使用了真拷貝來(lái)拷貝arr數(shù)組。我們使用了System.arraycopy()方法來(lái)拷貝數(shù)組,這個(gè)方法會(huì)創(chuàng)建一個(gè)新的數(shù)組來(lái)儲(chǔ)存原始數(shù)組的所有元素。所以當(dāng)我們修改arrCopy中的第一個(gè)元素時(shí),原始arr數(shù)組不會(huì)被修改,因?yàn)樗鼈兎謩e指向不同的內(nèi)存地址。
在Java中,我們可以通過(guò)使用clone()方法和序列化(serialization)來(lái)實(shí)現(xiàn)深度拷貝。
需要注意的是,Java中的所有基本類型都是通過(guò)值傳遞的,而不是引用傳遞。所以,當(dāng)我們對(duì)基本類型進(jìn)行拷貝時(shí),它們總是進(jìn)行真拷貝。