Java中的對象拷貝方式有兩種:深拷貝和淺拷貝。深拷貝和淺拷貝在實(shí)現(xiàn)上都是將一個(gè)對象的值拷貝給另一個(gè)對象,但是兩者之間有著本質(zhì)上的區(qū)別。
淺拷貝(Shallow Copy),是指復(fù)制對象時(shí),只是將對象的引用地址所指向的內(nèi)存區(qū)域復(fù)制給一個(gè)新的對象。這種方式只復(fù)制對象本身,而不復(fù)制對象所引用的其他對象。即原始對象和拷貝對象只是簡單地引用同一個(gè)對象,修改其中一個(gè)對象的屬性值會影響另一個(gè)對象,所以淺拷貝拷貝的是指針,而不是內(nèi)存中的內(nèi)容。
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),是指完全復(fù)制一份數(shù)據(jù)到另一塊內(nèi)存區(qū),兩個(gè)對象完全獨(dú)立,互不干擾。深拷貝不僅需要復(fù)制本身的對象,同時(shí)也要復(fù)制所引用的對象。即當(dāng)對象中引用其他對象時(shí),深拷貝將遞歸地拷貝整個(gè)對象樹。
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()); // 江蘇省