?浅拷贝是一个按位拷贝对象,它将创建一个具有原始对象属性值的新对象。如果属性是基本类型,则复制为基本类型的值;如果属性是内存地址(引用类型),则复制为内存地址 ,因此,如果一个对象改变了地址,就会影响另一个对象。
?深拷贝复制变量值。对于引用的数据,在复制之前将其递归基本类型。深拷贝后的对象与原对象完全隔离,不相互影响。对一个对象的修改不会影响另一个对象。与浅拷贝相比,深拷贝速度慢,成本高。
?一般来说,当引用指向值发生变化时,复制浅拷贝的引用也会发生变化;深拷贝与原对象完全隔离,不相互影响。
实现深拷贝的主要方法有两种:
推荐】慎用 Object 的 clone 复制对象的方法。 说明: 对象的 clone 默认的方法是浅拷贝。如果你想实现深度拷贝,你需要重写 clone 该方法可以复制属性对象。
与通过重写clone浅拷贝的基本思路是一样的,只需要实现对象图每层的每个对象Clonneable接口并重写clone方法,最后在顶层类重写clone调用方法中的clone该方法可以实现深度复制。简单地说,每层的每个对象都是浅复制的=深拷贝。
虽然层次调用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;
}
}