JAVA对象的浅克隆和深克隆

浅克隆

  • 对于基本数据类型的属性,复制一份给新的对象。
  • 对于非基本数据类型的属性(对象),复制一份对象的引用给新的对象。
    (即,新对象和旧对象中的非基本数据类型的属性的“指针” 指向同一个对象)

浅克隆步骤

  1. 实现java.lang.Cloneable接口
  2. 重写java.lang.Object.clone方法

代码

class Test{
    
}

class Father implements Cloneable {
    int i=5;
    Test test = new Test();

    public void setI(int i) {
        this.i = i;
    }

    @Override
    protected Object clone() {
        try{
            return super.clone();
        }catch (CloneNotSupportedException e){
            return null;
        }
    }

    public static void main(String[] args) {
        Father father = new Father();
        //修改基本数据类型
        father.setI(10);
        //执行clone方法
        Father clone =(Father) father.clone();

        System.out.println(clone.i);
        System.out.println(clone.test ==father.test);
        System.out.println(father==clone);

    }
}

运行结果

10
true
false

Process finished with exit code 0

深克隆

与浅克隆的区别是,对于非基本数据类型的属性,复制的不是原来的引用。
(即,新对象和旧对象中的非基本数据类型的属性的“指针” 不是 指向同一个对象)

深克隆步骤

  1. 实现java.io.Serializable
  2. 实现clone方法,将对象序列化转换为字节流,再将字节流反序列化为对象返回即可

代码

class Test implements  Serializable{

}

class Father implements Serializable {
    int i=5;
    Test test = new Test();

    public void setI(int i) {
        this.i = i;
    }

    public Father clone(){
        try {
            // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝    
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream objout = new ObjectOutputStream(byteOut);
            objout.writeObject(this);
            //将流序列化成对象
            ByteArrayInputStream bytein = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream objin = new ObjectInputStream(bytein);
            return (Father) objin.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        Father father = new Father();
        //修改基本数据类型
        father.setI(10);
        //执行clone方法
        Father clone =(Father) father.clone();

        System.out.println(clone.i);
        System.out.println(clone.test ==father.test);
        System.out.println(father==clone);

    }
}

运行结果

10
false
false

Process finished with exit code 0

Tip:

实际场景中,很少使用克隆,更多的是对象属性之间的克隆。
一般使用BeanUtils工具类的public static void copyProperties(Object source, Object target)方法。

原文地址:https://www.cnblogs.com/bendandedaima/p/13532103.html