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-hant/n/207083.html