Java的深度克隆和浅度克隆

克隆实现

Object类里有个clone方法,使用clone方法复制一个对象

克隆测试

public class Car {

    private int color;

    private String name;

    private int[] gls;

    private Object engine;

    public void setColor(int color) {
        this.color = color;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setGls(int[] gls) {
        this.gls = gls;
    }

    public void setEngine(Object engine) {
        this.engine = engine;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Car car = new Car();
        car.setColor(1);
        car.setGls(new int[]{1, 2, 3, 4});
        car.setName("daben");
        car.setEngine(new Engine("asdf"));

        Object clone = car.clone();
        
    }
}

输出结果

Exception in thread "main" java.lang.CloneNotSupportedException: com.xwf.gx.design.clonetest.Car
	at java.base/java.lang.Object.clone(Native Method)
	at com.xwf.gx.design.clonetest.Car.main(Car.java:40)

实现方式:
Cloneable 接口标识可合法调用 clone() ,类似Serializable,RandomAccess 接口

public class Engine {

    public String engineName;

    public Engine(String engineName) {
        this.engineName = engineName;
    }
}

public class Car implements Cloneable {

    public int color; //基本类型

    public String name; //引用类型

    public Engine engine; //引用类型

    public void setColor(int color) {
        this.color = color;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Car car = new Car();
        car.setColor(1);
        car.setName("daben");
        car.setEngine(new Engine("asdf"));

        Car car2 = (Car) car.clone();
        System.out.println(car);
        System.out.println(car2);
        System.out.println("car ? " + (car2 == car));
        System.out.println("color ? " + (car2.color == car.color));
        System.out.println("name ? " + (car2.name == car.name));
        System.out.println("engine ? " + (car2.engine == car.engine));

        System.out.println("1car color : " + car.color);
        System.out.println("1car2 color : " + car2.color);
        System.out.println("1car name : " + car.name);
        System.out.println("1car2 name : " + car2.name);
        System.out.println("1car engine : " + car.engine);
        System.out.println("1car2 engine : " + car2.engine);

        car2.name = "baoma";
        car2.color = 2;
        car2.engine.engineName = "new name";

        System.out.println("2car color : " + car.color);
        System.out.println("2car2 color : " + car2.color);
        System.out.println("2car name : " + car.name);
        System.out.println("2car2 name : " + car2.name);
        System.out.println("2car engine : " + car.engine.engineName);
        System.out.println("2car2 engine : " + car2.engine.engineName);
    }
    结果:
    com.xwf.gx.design.clonetest.Car@2f7c7260
	com.xwf.gx.design.clonetest.Car@2d209079
	car ? false
	color ? true
	name ? true
	engine ? true
	1car color : 1
	1car2 color : 1
	1car name : daben
	1car2 name : daben
	1car engine : com.xwf.gx.design.clonetest.Engine@6bdf28bb
	1car2 engine : com.xwf.gx.design.clonetest.Engine@6bdf28bb
	2car color : 1
	2car2 color : 2
	2car name : daben
	2car2 name : baoma
	2car engine : new name
	2car2 engine : new name

实现clone接口,运行正常。

浅克隆

上面例子就是浅克隆
输出结果总结一下:
对象复制成功 car 和 car2 是两个不同的对象
基本类型color 值复制
引用类型name engine 复制的是引用,指向的还是car里的对象

深度克隆实现方式

既然引用类型无法被完全克隆,那将引用类型也实现Cloneable接口重写clone方法

public class Engine implements Cloneable {

    public String engineName;

    public Engine(String engineName) {
        this.engineName = engineName;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Car implements Cloneable {

    public int color; //基本类型

    public String name; //引用类型

    public Engine engine; //引用类型

    public void setColor(int color) {
        this.color = color;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Car car2 = (Car) super.clone();
        car2.engine = (Engine) engine.clone();
        return car2;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Car car = new Car();
        car.setColor(1);
        car.setName("daben");
        car.setEngine(new Engine("asdf"));

        Car car2 = (Car) car.clone();
        System.out.println(car);
        System.out.println(car2);
        System.out.println("car ? " + (car2 == car));
        System.out.println("color ? " + (car2.color == car.color));
        System.out.println("name ? " + (car2.name == car.name));
        System.out.println("engine ? " + (car2.engine == car.engine));

        System.out.println("1car color : " + car.color);
        System.out.println("1car2 color : " + car2.color);
        System.out.println("1car name : " + car.name);
        System.out.println("1car2 name : " + car2.name);
        System.out.println("1car engine : " + car.engine);
        System.out.println("1car2 engine : " + car2.engine);

        car2.name = "baoma";
        car2.color = 2;
        car2.engine.engineName = "new name";

        System.out.println("2car color : " + car.color);
        System.out.println("2car2 color : " + car2.color);
        System.out.println("2car name : " + car.name);
        System.out.println("2car2 name : " + car2.name);
        System.out.println("2car engine : " + car.engine.engineName);
        System.out.println("2car2 engine : " + car2.engine.engineName);
    }

     /*System.out.println(car.engine);
        System.out.println(car2.engine);
        System.out.println(car);
        System.out.println(car2);
        car2.setColor(33);
        System.out.println(car.color);
        System.out.println(car2.color);
    //System.out.println(car.engine == car2.engine);
//        System.out.println(Objects.equals(car.color, car2.color));
//        System.out.println(Objects.equals(car.engine, car2.engine));
//        System.out.println(Objects.equals(car.gls, car2.gls));
//        System.out.println(Objects.equals(car.name, car2.name));
    car2.engine.engineName = "1";
        System.out.println(car.engine.engineName);
        System.out.println(car2.engine.engineName);*/
}
执行结果:
com.xwf.gx.design.clonetest.Car@2f7c7260
com.xwf.gx.design.clonetest.Car@2d209079
car ? false
color ? true
name ? true
engine ? false
1car color : 1
1car2 color : 1
1car name : daben
1car2 name : daben
1car engine : com.xwf.gx.design.clonetest.Engine@6bdf28bb
1car2 engine : com.xwf.gx.design.clonetest.Engine@6b71769e
car ? false
color ? false
name ? false
engine ? false
2car color : 1
2car2 color : 2
2car name : daben
2car2 name : baoma
2car engine : asdf
2car2 engine : new name

输出结果总结一下:
对象复制成功 car 和 car2 是两个不同的对象
基本类型color 值复制
引用类型name engine 变成了不同的对象
深度克隆可以把引用类型的变量也复制一份,不和原对象公用一个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值