警惕陣列的淺拷貝

2021-09-22 08:39:07 字數 1930 閱讀 3671

一、分析

在日常工作中,我們會遇見很多陣列的拷貝和複製的問題,但是在你使用系統提供的api進行編碼的時候,無形中會留下淺拷貝的隱患。

二、場景

有這樣乙個例子,第乙個箱子裡面與赤橙黃綠青藍紫7色氣球,現在希望第二個箱子也放入7個氣球,其中最後乙個氣球改為藍色,也就是赤橙黃綠青藍藍七個氣球。

1

import

org.apache.commons.lang3.builder.tostringbuilder;23

public

class

client

1314

//第二個箱子的小球是拷貝的第乙個箱子裡的

15 ballon box2 =arrays.copyof(box1,box1.length);

16//

修改最後乙個氣球的顏色

17 box2[6].setcolor(color.blue);

18//

列印出第乙個箱子中的氣球顏色

19for

(ballon b:box1)

22}

23}

2425

//氣球的顏色

26enum

color

2930

//氣球

31class

ballon

4041

public

void setid(int

id)

4445

public

color getcolor()

4849

public

void

setcolor(color color)

5253

public ballon(color _color,int

_id)

5758

/*id、color的getter/setter方法省略

*/59

//apache-common包下的tostringbuilder重寫tostring方法

60public

string tostring()

63 }

第二個箱子的最後乙個氣球毫無疑問是被修改了藍色,不過是通過拷貝第乙個箱子的氣球實現的,那麼會對第乙個箱子的氣球顏色有影響嗎?輸出結果:

balloon@b2fd8f[編號=0,顏色=red]

balloon@a20892[編號=1,顏色=orange]

balloon@158b649[編號=2,顏色=yellow]

balloon@1037c71[編號=3,顏色=green]

balloon@1546e25[編號=4,顏色=indigo]

balloon@8a0d5d[編號=5,顏色=blue]

balloon@a470b8[編號=6,顏色=blue]

最後乙個氣球竟然被修改了。這是為何?

這是典型的淺拷貝(shallow clone)問題,通過copyof()方法產生的陣列是乙個淺拷貝引用位址。需要說明的是陣列的clone()方法也是與此相同,同樣是淺拷貝,而且集合的clone()方法也是淺拷貝。這就需要大家多留心了。

問題找到了,解決辦法也很簡單,遍歷box1的每個元素,重新生成乙個氣球(ballon)物件,並放置到box2陣列中。

很多地方使用集合(如list)進行業務處理時,比如發覺需要拷貝集合中的元素,可集合沒有提供任何拷貝方法,所以乾脆使用 list.toarray方法轉換成陣列,然後通過arrays.copyof拷貝,然後轉換成集合,簡單便捷!但是,非常遺憾,這裡我們有撞到淺拷貝的 槍口上了!!!!

三、建議

雖然很多時候淺拷貝可以解決業務問題,但更多的時候會留下隱患,需要我們提防又提防。

陣列拷貝(深拷貝 淺拷貝)

底層都是使用system.arraycopy object src,int srcpos,object dest,int destpos,int length 方法完成陣列元素拷貝任務的 方法說明 如果newlength original.length,那麼會將原陣列中前newlength個元素拷貝...

陣列淺拷貝的方式

首先 let arr1 1,2,3 let arr2 arr1 肯定是不行的 記錄一下幾種簡單的方法.let arr2 arr1 let arr2 arr1.concat let arr2 arr1.slice 順便寫一下自己寫的物件深拷貝的方法,const test test.loop test ...

陣列,物件的深拷貝 與 淺拷貝

淺拷貝 object.assign let arr1 1,23,54 let arr2 object.assign arr1 console.log arr1 arr2 result true let obj1 let obj2 object.assign obj1 console.log obj1...