天天看点

谈谈浅复制和深复制的想法浅复制和深复制的概念手写浅复制和深复制Java提供的接口

浅复制和深复制的概念

复制在Java中一般是复制一个已经存在的对象,我们都知道Java中有基本数据类型和引用数据类型,也正是因为这样,才会有浅复制和深复制的说法。

浅复制:如果是基本数据类型的话,会将值复制一份,如果是引用类型的话,会将引用变量复制一份,但是指向的还是同一个实例对象。

深复制:针对引用数据类型而来,意味复制的是实例对象的内容,而不是复制引用变量。

谈谈浅复制和深复制的想法浅复制和深复制的概念手写浅复制和深复制Java提供的接口

从图中可以看出,引用数据类型也被拷贝了一份,这样就可以单独进行修改而不影响原来的值。

下面就用两种方式来写浅复制和深复制:手写+Java提供的接口

手写浅复制和深复制

public class Color {
    private String colorName;
    public Color(String colorName) {
        this.colorName = colorName;
    }
    public String getColorName() {
        return colorName;
    }

}
           
public class Car implements Cloneable {
    private String name;
    private float price;
    private Color color;
    public Car(String name, float price, Color color) {
        this.name = name;
        this.price = price;
        this.color = color;
    }
    public Car copy() {
        // 重写new一个color,放到要复制的car对象中
        Color color = new Color(this.color.getColorName());
        // 重新new出一个Car对象并返回,这就是复制的一个独立的对象
        Car car = new Car(this.name, this.price, color);
        return car;
    }
}
           

Java提供的接口

Java提供了一个Cloneable接口,用来标志该类可以被克隆,如果实现了这个接口,那么就需要重写clone方法,在这个方法里面进行深复制的过程。

public class Color implements Cloneable {
    private String colorName;

    public Color(String colorName) {
        this.colorName = colorName;
    }

    public String getColorName() {
        return colorName;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
           
public class Car implements Cloneable {
    private String name;
    private float price;
    private Color color;

    public Car(String name, float price, Color color) {
        this.name = name;
        this.price = price;
        this.color = color;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 此时的car对象中的color和this的car对象中的color指向的是同一个color对象
        Car car = (Car) super.clone();
        // 进一步拷贝复制
        car.color = (Color) this.color.clone();
        return car;
    }
}
           

上面两中方式都很好测试,作者在实验的时候有个疑问:String类型是引用类型的,但是在浅复制的时候,String类型好像复制的并不是引用而是字符串的值,这就让我很纳闷了,索性暂时当做是特殊的类型来处理了。如果有哪位小伙伴可以告知的话,希望可以留言。

继续阅读