java如何实现深拷贝
Java浅拷贝
- 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
Java深拷贝
- 深拷贝复制变量值,对于引用数据,则递归至基本类型后,再复制。深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象。深拷贝相比于浅拷贝速度较慢并且花销较大。
Java浅拷贝和深拷贝的区别是什么?
- 通俗来讲浅拷贝的复制其引用,当引用指向的值改变时也会跟着变化;而深拷贝则是与原来的对象完全隔离,互不影响。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jx5gcOnw-1681775781812)(C:\Users\quyanliang\AppData\Roaming\Typora\typora-user-images\1681775700804.png)]](https://img-blog.csdnimg.cn/0f1f66c00e0d440ea2559ded25680c0c.png) 
深拷贝的实现方法主要有两种:
-  (1) 通过重写clone方法来实现深拷贝(实现Cloneable接口) 
-  慎用 Object 的 clone 方法来拷贝对象。 
-  说明: 对象的 clone 方法默认是浅拷贝,若想实现深拷贝需要重写 clone 方法实现属性对象的拷贝。 
-  与通过重写clone方法实现浅拷贝的基本思路一样,只需要为对象图的每一层的每一个对象都实现Clonneable接口并重写clone方法,最后在最顶层的类的重写的clone方法中调用所有的clone方法即可实现深拷贝。简单的说就是“每一层的每个对象都进行浅拷贝=深拷贝。 
-  (2)推荐: 通过对象序列化实现深拷贝(实现Serializable接口) 
-  虽然层次调用clone方法可以实现深拷贝,但是显然代码量实在太大。特别对于属性数量比较多、层次比较深的类而言,每个类都要重写clone方法太过繁琐。 
-  将对象序列化为字节序列后,默认会将该对象的整个对象图进行序列化,再通过反序列即可完美地实现深拷贝。 
-  import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ObSriaInOut { public static void main(String[] args) throws IOException, ClassNotFoundException { Persen p = in (); Persen p2 = out(); System.out.println(p); System.out.println(p2); } public static Persen out() throws IOException, FileNotFoundException { //创建对象输出流,在使用对象输出流时必须进行对象序列化,否则会报错java.io.NotSerializableException ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("f:\\person.bin", false)); //床架你一个persn对象 Persen p = new Persen("张大", 22, 5000); //写出对象流 oos.writeObject(p); //关闭流 oos.flush(); oos.close(); return p; } public static Persen in () throws IOException, FileNotFoundException, ClassNotFoundException { //创建对象输入流 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("f:\\person.bin")); //读取对象流 Persen p = (Persen) ois.readObject(); ois.close(); System.out.println(p.toString()); return p; } }
-  persen类 
-  package com.javabase.obj.serializable; import java.io.Serializable; public class Persen implements Serializable { private String name; private double sal; private int age; public Persen() { super(); } //构造方法用于初始化成员参数 public Persen(String name, double sal, int age) { super(); this.name = name; this.sal = sal; this.age = age; } @Override public String toString() { return this.name + "---" + this.age + "---" + this.sal; } }



















![[2019.01.25]Android NDK Crash错误定位](https://img-blog.csdnimg.cn/0e6ca17a7cf54eb2b11b5eedf6626f27.png)