在某些场景中,我们需要获取到一个对象的拷贝用于某些处理。这时候就可以用到Java中的Object.clone方法进行对象复制,得到一个一模一样的新对象。但是在实际使用过程中会发现:当对象中含有可变的引用类型属性时,在复制得到的新对象对该引用类型属性内容进行修改,原始对象响应的属性内容也会发生变化,这就是"浅拷贝"的现象。
Address类:clone/Address.java
package clone; public class Address implements Cloneable{//实现cloneable接口 private String province; private String city; public Address() { } public Address(String province, String city) { this.province = province; this.city = city; } public Address clone() throws CloneNotSupportedException { Address newAdd = (Address)super.clone(); return newAdd; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String toString() { return "Province:"+province+" city:"+city; } }
student类:clone/student.java
package clone; public class student implements Cloneable{ private String name;//String被声明为final,是不可变类型,无法修改,所以就算是浅复制也不影响。 private int age;//基本类型,clone的时候直接copy private Address address;//Address不是基本类型,并且可变,默认的clone的时候只会复制一个引用,这样clone前后的两个对象都引用同一个Address实例对象。 public student() { } public student(String name,int age, Address address) { this.name = name; this.age = age; this.address = address; } public student clone() throws CloneNotSupportedException { student newStu = (student) super.clone(); newStu.address = (Address) address.clone();//不加这一句,对于Address来说就是一个浅复制。 return newStu; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String toString() { return "name:"+name+" age:"+age+"Address Info:"+address.toString(); } }
test类: clone/test.java
package clone; public class test { public static void main(String[] args) throws CloneNotSupportedException { Address add = new Address("四川","成都"); student a = new student("小明",18,add); student b = a.clone();//克隆a,赋值给b add.setCity("广安");//浅复制的话,a和b都引用add这个实例对象,则此次修改值势必会影响a和b。深复制则不影响。 System.out.println(a.toString()); System.out.println(b.toString()); } }
输出
name:小明 age:18Address Info:Province:四川 city:广安
name:小明 age:18Address Info:Province:四川 city:成都
从输出结果来看,对add实例对象的修改并没有影响到b这个引用变量,所以本次clone不是浅复制。
原文:https://www.cnblogs.com/xxxxxiaochuan/p/13715104.html