Java中的對象拷貝方式有兩種:深拷貝和淺拷貝。深拷貝和淺拷貝在實現上都是將一個對象的值拷貝給另一個對象,但是兩者之間有著本質上的區別。
淺拷貝(Shallow Copy),是指復制對象時,只是將對象的引用地址所指向的內存區域復制給一個新的對象。這種方式只復制對象本身,而不復制對象所引用的其他對象。即原始對象和拷貝對象只是簡單地引用同一個對象,修改其中一個對象的屬性值會影響另一個對象,所以淺拷貝拷貝的是指針,而不是內存中的內容。
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public Person clone() { try { return (Person) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } } Person p1 = new Person("Tom", 18); Person p2 = p1.clone(); // 淺拷貝 p1.setAge(20); System.out.println(p1.getAge()); // 20 System.out.println(p2.getAge()); // 20
深拷貝(Deep Copy),是指完全復制一份數據到另一塊內存區,兩個對象完全獨立,互不干擾。深拷貝不僅需要復制本身的對象,同時也要復制所引用的對象。即當對象中引用其他對象時,深拷貝將遞歸地拷貝整個對象樹。
public class Person implements Cloneable { private String name; private int age; private Address address; public Person(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public Person clone() { try { Person person = (Person) super.clone(); person.address = this.address.clone(); return person; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } } public class Address implements Cloneable { private String province; private String city; public Address(String province, String city) { this.province = province; this.city = city; } public void setProvince(String province) { this.province = province; } public String getProvince() { return province; } public void setCity(String city) { this.city = city; } public String getCity() { return city; } @Override public Address clone() { try { return (Address) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } } Address address = new Address("江蘇省", "南京市"); Person person1 = new Person("Tom", 18, address); Person person2 = person1.clone(); // 深拷貝 person1.setAge(20); address.setProvince("北京市"); System.out.println(person1.getAge()); // 20 System.out.println(person1.getAddress().getProvince()); // 北京市 System.out.println(person2.getAge()); // 18 System.out.println(person2.getAddress().getProvince()); // 江蘇省