在Java中,對象克隆分為深克隆和淺克隆兩種類型。深克隆指的是將一個對象完整地復(fù)制,包括它的所有屬性,而淺克隆則只是復(fù)制了對象本身,其屬性還是由原對象共用。
深克隆一般有兩種實現(xiàn)方式,即使用重寫Object類的clone方法和使用序列化反序列化的方式。
/** * 重寫Object類的clone方法實現(xiàn)深克隆 */ public class Person implements Cloneable{ private String name; private Address address; public Person(String name, Address address) { this.name = name; this.address = address; } @Override public Object clone() throws CloneNotSupportedException { Person person = (Person) super.clone(); person.address = (Address) address.clone(); return person; } //getters and setters } public class Address implements Cloneable{ private String city; private String street; public Address(String city, String street) { this.city = city; this.street = street; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } //getters and setters } //使用 Address address = new Address("Beijing", "Chaoyang"); Person person1 = new Person("John", address); Person person2 = (Person) person1.clone(); System.out.println(person1 == person2); //false System.out.println(person1.getAddress() == person2.getAddress()); //false
從上述代碼中可以看出,當(dāng)我們想要實現(xiàn)深克隆時,需要將實例化對象中的所有引用類型的屬性進行克隆,即使用該類型的clone方法進行克隆,而如果該類型沒有實現(xiàn)Cloneable接口,則必須手動書寫clone方法。
而淺克隆則較為簡單,只需要在對象上實現(xiàn)Cloneable接口即可,但是需要注意的是,克隆出來的對象并沒有完全獨立于原對象,它們還會共享一些屬性。
/** * 實現(xiàn)Cloneable接口的對象實現(xiàn)淺克隆 */ public class Computer implements Cloneable{ private String brand; private String model; private Memory memory; public Computer(String brand, String model, Memory memory) { this.brand = brand; this.model = model; this.memory = memory; } public Object clone() throws CloneNotSupportedException { return super.clone(); } //getters and setters } public class Memory{ private int size; public Memory(int size) { this.size = size; } //getters and setters } //使用 Memory memory = new Memory(16); Computer computer1 = new Computer("Apple", "MacBook Pro", memory); Computer computer2 = (Computer) computer1.clone(); System.out.println(computer1 == computer2); //false System.out.println(computer1.getMemory() == computer2.getMemory()); //true
從上述代碼中可以看出,淺克隆出來的對象始終還會共享一些屬性,上述代碼中computer1和computer2共用了同一個Memory對象。