List<Integer> list1 = new ArrayList<>();
list1.add(1);
List<Integer> list2 = list1;
list1.add(2);
代碼執(zhí)行完畢之后,list2將包含整數(shù)1和2。
而以下代碼則是深拷貝:
List<Integer> list1 = new ArrayList<>();
list1.add(1);
List<Integer> list2 = new ArrayList<>(list1);
list1.add(2);
代碼執(zhí)行完畢之后,list2將只包含整數(shù)1,不包含整數(shù)2。
Immutable對(duì)象:上述情形如果遇到immutable對(duì)象,即不可變對(duì)象,其實(shí)是不需要深拷貝的(不僅不需要,還應(yīng)該杜絕拷貝,因?yàn)榧儗倮速M(fèi))。但是前提是對(duì)象是真正的immutable。反面例子為:
public class NonStrictlyImmutable {
private final List<Integer> mList = new ArrayList<>();
public List<Integer> getList() {
return mList;
}
}
mList成員設(shè)置為了private final,NonStrictlyImmutable對(duì)象實(shí)例化完成后mList所引用的實(shí)際對(duì)象也不可再被改變,然而mList這個(gè)List的元素確是可以改變的,nonStrictlyImmutable.getList().add(1)并不會(huì)報(bào)編譯錯(cuò)誤,而這一行代碼卻實(shí)實(shí)在在改變了nonStrictlyImmutable對(duì)象的值!
而如果getList()函數(shù)不直接返回mList引用,創(chuàng)建一個(gè)副本,或者使其不可被改變,則可以達(dá)到”嚴(yán)格意義上的“immutable。例如:
public class NonStrictlyImmutable {
private final List<Integer> mList = new ArrayList<>();
public List<Integer> getList() {
// 以下兩種方式都可以,各有優(yōu)劣
// return new ArrayList<>(mList);
// return Collections.unmodifiableList(mList);
return Collections.unmodifiableList(mList);
}
}
上面兩種方式各有優(yōu)劣:前者允許對(duì)新獲取到的副本進(jìn)行修改操作而不會(huì)拋出異常,但會(huì)把底層數(shù)組數(shù)據(jù)創(chuàng)建多份;后者不會(huì)創(chuàng)建多份底層數(shù)組數(shù)據(jù),但是如果對(duì)getList()返回的引用進(jìn)行修改操作,將會(huì)拋出異常;見(jiàn)仁見(jiàn)智。