Object類中的clone()方法是Java中的一個重要方法,這個方法可以返回一個對象的「淺拷貝」,也就是對原對象中的內容進行複製,但不會複製原對象指向的對象。深入掌握這個方法,將對Java工程師的職業發展帶來很大幫助。
一、clone()方法的使用和作用
clone()方法的作用是生成一個與原對象相同的新對象。使用clone()方法時,需要實現Cloneable接口,否則會拋出CloneNotSupportedException異常。
以下是使用clone方法實現淺拷貝的示例:
class Person implements Cloneable{
private String name;
private int age;
private ArrayList skills;
public Person(String name, int age, ArrayList skills) {
this.name = name;
this.age = age;
this.skills = skills;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
ArrayList skills = new ArrayList();
skills.add("Java");
skills.add("Spring");
Person person = new Person("Tom", 23, skills);
Person cloned = (Person) person.clone();
System.out.println(person == cloned); //false
System.out.println(person.getName() == cloned.getName()); //true
System.out.println(person.getSkills() == cloned.getSkills()); //true
}
}
從輸出的結果可以看到,淺拷貝後,原對象和新對象指向的ArrayList對象是一個,但是Person對象不是同一個。
二、淺拷貝和深拷貝的區別
淺拷貝
clone()方法實現的是淺拷貝,也就是說,如果對象的屬性是基本類型或不可變類型,可以實現一個副本,不影響原對象。但如果屬性是可變對象,如ArrayList,淺拷貝只會拷貝引用,而不會將ArrayList中的值也進行拷貝,使得原對象與新對象的引用相同。
深拷貝
深拷貝則是對可變對象進行遞歸拷貝,最終生成一個新的對象,使得原對象與新對象沒有任何關係,可以互不干擾。
以下是深拷貝的示例:
public class Person implements Cloneable {
private String name;
private int age;
private ArrayList skills;
public Person(String name, int age, ArrayList skills) {
this.name = name;
this.age = age;
this.skills = skills;
}
@Override
public Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.skills = (ArrayList) this.skills.clone();
return cloned;
}
//省略訪問器
}
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
ArrayList skills = new ArrayList();
skills.add("Java");
skills.add("Spring");
Person person = new Person("Tom", 23, skills);
Person cloned = (Person) person.clone();
System.out.println(person == cloned); //false
System.out.println(person.getSkills() == cloned.getSkills()); //false
}
}
從輸出結果中,可以看出原對象與克隆對象沒有任何關係,擁有自己獨立的ArrayList對象。
三、實現clone()方法需要注意的細節
1、需要實現Cloneable接口
在使用clone()方法之前,需要實現Cloneable接口,否則會拋出CloneNotSupportedException異常。
2、需要重寫clone()方法
重寫clone()方法時,需要注意clone()方法是protected類型,需要使用public類型覆蓋這個方法,並且要調用super.clone()方法來得到一個新的實例。返回的對象必須向下轉型為正確的類型。
3、注意引用對象的問題
如果被克隆對象有引用類型的屬性時,可以通過new一個新的對象進行深拷貝。
除此之外,還可以使用序列化實現深度拷貝,在序列化後再反序列化得到一個新的對象。
四、總結
深入掌握Object.clone()方法,能夠讓我們更好的處理對象克隆時的問題,從而提高Java工程師的職業發展水平。越來越多的框架和庫要求我們實現cloneable接口,因此,掌握clone()方法將對我們的工作帶來幫助。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/207083.html
微信掃一掃
支付寶掃一掃