Java-Object.clone()-淺複製與深複製
阿新 • • 發佈:2020-09-22
引言
在某些場景中,我們需要獲取到一個物件的拷貝用於某些處理。這時候就可以用到Java中的Object.clone方法進行物件複製,得到一個一模一樣的新物件。但是在實際使用過程中會發現:當物件中含有可變的引用型別屬性時,在複製得到的新物件對該引用型別屬性內容進行修改,原始物件響應的屬性內容也會發生變化,這就是"淺拷貝"的現象。
淺拷貝的例子
Address類:clone/Address.java
package clone; public class Address implements Cloneable{//實現cloneable介面 private String province;private String city; public Address() { } public Address(String province, String city) { this.province = province; this.city = city; } public Address clone() throws CloneNotSupportedException { Address newAdd = (Address)super.clone(); returnnewAdd; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; }public String toString() { return "Province:"+province+" city:"+city; } }
student類:clone/student.java
package clone; public class student implements Cloneable{ private String name;//String被宣告為final,是不可變型別,無法修改,所以就算是淺複製也不影響。 private int age;//基本型別,clone的時候直接copy private Address address;//Address不是基本型別,並且可變,預設的clone的時候只會複製一個引用,這樣clone前後的兩個物件都引用同一個Address例項物件。 public student() { } public student(String name,int age, Address address) { this.name = name; this.age = age; this.address = address; } public student clone() throws CloneNotSupportedException { student newStu = (student) super.clone(); newStu.address = (Address) address.clone();//不加這一句,對於Address來說就是一個淺複製。 return newStu; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String toString() { return "name:"+name+" age:"+age+"Address Info:"+address.toString(); } }
test類: clone/test.java
package clone; public class test { public static void main(String[] args) throws CloneNotSupportedException { Address add = new Address("四川","成都"); student a = new student("小明",18,add); student b = a.clone();//克隆a,賦值給b add.setCity("廣安");//淺複製的話,a和b都引用add這個例項物件,則此次修改值勢必會影響a和b。深複製則不影響。 System.out.println(a.toString()); System.out.println(b.toString()); } }
輸出
name:小明 age:18Address Info:Province:四川 city:廣安
name:小明 age:18Address Info:Province:四川 city:成都
從輸出結果來看,對add例項物件的修改並沒有影響到b這個引用變數,所以本次clone不是淺複製。