java深拷贝和浅拷贝
拷贝,什么意思?就用一个例子来说明:对象A和对象B都属于类S,具有属性a和b。那么对对象A进行拷贝操作赋值给对象B就是:B.a=A.a; B.b=A.b
在任何语言中,都有浅拷贝和深拷贝的概念,java也不例外。
参考博客:https://www.cnblogs.com/shakinghead/p/7651502.html
深拷贝和浅拷贝的区别
如果在拷贝对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。
浅拷贝(参考其他博客)
/* 拷贝构造方法实现浅拷贝 */ public class CopyConstructor { public static void main(String[] args) { Age a=new Age(20); Person p1=new Person(a,"摇头耶稣"); Person p2=new Person(p1); System.out.println("p1是"+p1); System.out.println("p2是"+p2); //修改p1的各属性值,观察p2的各属性值是否跟随变化 p1.setName("小傻瓜"); a.setAge(99); System.out.println("修改后的p1是"+p1); System.out.println("修改后的p2是"+p2); } } class Person{ //两个属性值:分别代表值传递和引用传递 private Age age; private String name; public Person(Age age,String name) { this.age=age; this.name=name; } //拷贝构造方法 public Person(Person p) { this.name=p.name; this.age=p.age; } public void setName(String name) { this.name=name; } public String toString() { return this.name+" "+this.age; } } class Age{ private int age; public Age(int age) { this.age=age; } public void setAge(int age) { this.age=age; } public int getAge() { return this.age; } public String toString() { return getAge()+""; } }
运行结果为:
p1是摇头耶稣 20
p2是摇头耶稣 20
修改后的p1是小傻瓜 99
修改后的p2是摇头耶稣 99
深拷贝(同参考)
package linearList; /* 层次调用clone方法实现深拷贝 */ public class DeepCopy { public static void main(String[] args) { Age a=new Age(20); Student stu1=new Student("摇头耶稣",a,175); //通过调用重写后的clone方法进行浅拷贝 Student stu2=(Student)stu1.clone(); System.out.println(stu1.toString()); System.out.println(stu2.toString()); System.out.println(); //尝试修改stu1中的各属性,观察stu2的属性有没有变化 stu1.setName("大傻子"); //改变age这个引用类型的成员变量的值 a.setAge(99); //stu1.setaAge(new Age(99)); 使用这种方式修改age属性值的话,stu2是不会跟着改变的。因为创建了一个新的Age类对象而不是改变原对象的实例值 stu1.setLength(216); System.out.println(stu1.toString()); System.out.println(stu2.toString()); } } /* * 创建年龄类 */ class Age implements Cloneable{ //年龄类的成员变量(属性) private int age; //构造方法 public Age(int age) { this.age=age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return this.age+""; } //重写Object的clone方法 public Object clone() { Object obj=null; try { obj=super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } } /* * 创建学生类 */ class Student implements Cloneable{ //学生类的成员变量(属性),其中一个属性为类的对象 private String name; private Age aage; private int length; //构造方法,其中一个参数为另一个类的对象 public Student(String name,Age a,int length) { this.name=name; this.aage=a; this.length=length; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Age getaAge() { return this.aage; } public void setaAge(Age age) { this.aage=age; } public int getLength() { return this.length; } public void setLength(int length) { this.length=length; } public String toString() { return "姓名是: "+this.getName()+", 年龄为: "+this.getaAge().toString()+", 长度是: "+this.getLength(); } //重写Object类的clone方法 public Object clone() { Object obj=null; //调用Object类的clone方法——浅拷贝 try { obj= super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } //调用Age类的clone方法进行深拷贝 //先将obj转化为学生类实例 Student stu=(Student)obj; //学生类实例的Age对象属性,调用其clone方法进行拷贝 stu.aage=(Age)stu.getaAge().clone(); return obj; } }
运行结果:
姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
姓名是: 大傻子, 年龄为: 99, 长度是: 216
姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
分析结果可以验证:进行了深拷贝之后,无论是什么类型的属性值的修改,都不会影响另一个对象的属性值。
浙公网安备 33010602011771号