沧州网站排名优化,快速搭建网站框架的工具,网站页面如何设计,网店网站源码java深拷贝和浅拷贝的区别
深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体#xff0c;而不是引用。
假设B复制了A#xff0c;修改A的时候#xff0c;看B是否发生变化#xff1a;
如果B跟着也变了#xff0c;说明是浅拷贝#xff0c;拿人手短#xff…java深拷贝和浅拷贝的区别
深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体而不是引用。
假设B复制了A修改A的时候看B是否发生变化
如果B跟着也变了说明是浅拷贝拿人手短修改堆内存中的同一个值
如果B没有改变说明是深拷贝自食其力修改堆内存中的不同的值
1、浅拷贝
在拷贝一个对象时对对象的基本数据类型的成员变量进行拷贝但对引用类型的成员变量只进行引用的传递并没有创建一个新的对象当对引用类型的内容修改会影响被拷贝的对象。
只是增加了一个指针指向已存在的内存地址java中clone方法是一个浅拷贝引用类型依然在传递引用。
如果克隆对象的子对象是不可变的或者子对象没有更改器方法那么就是安全的
2、深拷贝
除了对基本数据类型的成员变量进行拷贝对引用类型的成员变量进行拷贝时创建一个新的对象来保存引用类型的成员变量。
增加了一个指针并且申请了一个新的内存使这个增加的指针指向这个新的内存。
重新定义clone方法克隆出所有子对象
Cloneable接口出现和接口的使用没有任何关系因为clone方法是Object类继承而来的
Cloneable接口是标记接口不含任何方法唯一的作用就是允许在类型查询中视同instanceof
实现深拷贝有两种方法
(1)序列化该对象然后反序列化回来就能得到一个新的对象了。 序列化将对象写入到IO流中 反序列化从IO流中恢复对象 序列化机制允许将实现序列化的java对象转化为字节序列这些字节序列可以保存到磁盘或者网络传输上以达到以后恢复成原来的对象序列化机制使得对象可以脱离程序的运行而独立存在。 (2)继续利用clone()方法对该对象的引用类型变量再实现一次clone()方法。
(1)序列化
public class Student3 implements Serializable,Cloneable{2 private static final long serialVersionUID 3462139480068147262L;3 private Integer age;4 private String name;5 6 public Student3(Integer age, String name) {7 this.age age;8 this.name name;9 }
10
11 public Integer getAge() {
12 return age;
13 }
14
15 public void setAge(Integer age) {
16 this.age age;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public void setName(String name) {
24 this.name name;
25 }
26
27 Override
28 protected Object clone() throws CloneNotSupportedException {
29 return super.clone();
30 }
31
32 public static void main(String[] args) throws CloneNotSupportedException {
33 File file new File(D:/test.txt);
34 Student3 stu new Student3(18, xiaoxian);
35
36 System.out.println(clone方法是浅拷贝);
37 Student3 clone (Student3)stu.clone();
38 System.out.println(clone stu的结果: (clonestu));
39 System.out.println(clone.name stu.name的结果: (clone.namestu.name));
40
41 System.out.println(将对象序列化是深拷贝);
42 //将对象序列化到IO流中
43 try {
44 ObjectOutputStream objectOutputStream new ObjectOutputStream(new FileOutputStream(file));
45 objectOutputStream.writeObject(stu);
46 objectOutputStream.close();
47 } catch (IOException e) {
48 e.printStackTrace();
49 }
50
51 //将对象从IO流中反序列化出来
52 try {
53 ObjectInputStream objectInputStream new ObjectInputStream(new FileInputStream(file));
54 Student3 student3 (Student3) objectInputStream.readObject();
55 System.out.println(student3 stu的结果:(stu student3));
56 System.out.println(student3.name stu.name的结果:(stu.name student3.name));
57 } catch (Exception e) {
58 e.printStackTrace();
59 }
60 }
61
62 }2重写clone方法
package com.company.DeepCopy;public class DeepCopy {public static void main(String[] args) {Age a new Age(20);Student stu1 new Student(宁采臣,a,174);//通过调用重写后的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(18);//stu1.setaAge(new Age(99)); 使用这种方式修改age属性值的话stu2是不会跟着改变的。因为创建了一个新的Age类对象而不是改变原对象的实例值stu1.setLength(157);System.out.println(stu1.toString());System.out.println(stu2.toString());}
}
package com.company.DeepCopy;public 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 getAge() {return this.aage;}public void setAge(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.getAge().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.getAge().clone();return obj;}
} package com.company.DeepCopy;public 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;}Overridepublic String toString() {return this.age;}//重写Object的clone方法public Object clone() {Object obj null;try {obj super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return obj;}
} Map集合的优缺点底层数据结构