浅拷贝与深拷贝问题

Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去。举例说明:比如,对象A和对象B都属于类S,具有属性a和b。那么对对象A进行拷贝操作赋值给对象B就是:B.a=A.a; B.b=A.b;

浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。

②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。为了解决这个问题,引入深拷贝

深拷贝 对于引用类型成员变量,比如数组或者类对象,深拷贝会在目标对象内新建一个对象空间,然后拷贝原对象对应成员变量实体对象里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。

在Java中 有一个方法为protected Object clone() throws CloneNotSupportedException,这个方法就是进行的浅拷贝。某个类要实现深拷贝 这个类需要实现Cloneable接口,然后对clone方法进行重写

重写clone方法定义:

class Car implements Cloneable{  //定义一个Car类 实现接口Cloneable
       //成员变量定义
   public Object clone(){  //重写clone方法
       Car c = null;
        try {
                c = (Car)super.clone(); //调用父类Object实现浅拷贝
               } catch (CloneNotSupportedException e) {
                        e.printStackTrace();
               }
            //编写代码实现深拷贝

      }
    //编写代码实现其他成员方法
}

Car 类中包含

1.属性:

private String name;
private CarDriver driver;
private int[] scores;

2.无参构造函数

public Car() {
}

3.成员方法:

@Override
public String toString() {
    return "Car [name=" + name + ", driver=" + driver + ", scores=" + Arrays.toString(scores) + "]";
}

4.其他get和set成员方法:public String getName() ,public CarDriver getDriver(),public int[] getScores()和

public void setName(String name),public void setDriver(CarDriver dr),public void setScores(int[] s)

及 clone方法实现深拷贝

CarDriver为已定义好的类,如下:

class CarDriver {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public CarDriver() {}
    public String toString() {
        return "CarDriver [name=" + name+"]";
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int i=sc.nextInt();
        switch(i) {
        case 1:     //深拷贝
            CarDriver cd=new CarDriver();
            Car c1=new Car();
            c1.setDriver(cd);
            cd.setName("d1");
            c1.setName("car1");
            int[] s=new int[2];
            c1.setScores(s);
            Car d1=(Car)c1.clone();
            System.out.println("c1:"+(c1==d1)+" driver:"+(c1.getDriver()==d1.getDriver())+" scores:"+(c1.getScores()==d1.getScores()));
            System.out.println(c1.toString()+" "+d1.getName()+" "+d1.getDriver().getName());    
            break;
        case 2: //        
            Car c2=new Car();
            Car d2=(Car)c2.clone();
            System.out.println("c2:"+(c2==d2)+" driver:"+c2.getDriver()+" "+(c2.getDriver()==d2.getDriver())+" scores:"+c2.getScores()+" "+(c2.getScores()==d2.getScores()));
            break;
        case 3:
            CarDriver cd1=new CarDriver();
            Car c3=new Car();
            c3.setDriver(cd1);
            Car d3=(Car)c3.clone();
            System.out.println("c3:"+(c3==d3)+" driver:"+c3.getDriver()+" "+(c3.getDriver()==d3.getDriver())+" scores:"+c3.getScores()+" "+(c3.getScores()==d3.getScores()));
            break;
        case 4:
            //CarDriver cd3=new CarDriver();
            Car c4=new Car();
            //c4.setDriver(cd3);
            int[] s1=new int[2];
            c4.setScores(s1);
            Car d4=(Car)c4.clone();
            System.out.println("c4:"+(c4==d4)+" driver:"+c4.getDriver()+" "+(c4.getDriver()==d4.getDriver())+" scores:"+" "+(c4.getScores()==d4.getScores()));
            break;

        } 
    }
}

//现在 你只需要在 下面 写上 Car类的完整代码 即可

源代码:

class Car implements Cloneable {  //定义一个Car类 实现接口Cloneable
    private String name;
    private CarDriver driver;
    private int[] scores;

    public Car() {
    }

    public Object clone() {  //重写clone方法
        Car c = null;
        try {
            c = (Car) super.clone(); //调用父类Object实现浅拷贝
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        //编写代码实现深拷贝
        if (driver != null) {
            CarDriver carDriver = new CarDriver();
            carDriver.setName(driver.getName());
            c.setDriver(carDriver);

        }
        
        if (scores != null) {
            int[] newScores = new int[scores.length];
            for (int i = 0; i < newScores.length; i++) {
                newScores[i] = scores[i];
            }
            c.setScores(newScores);
        }

        return c;

    }

    @Override
    public String toString() {
        return "Car [name=" + name + ", driver=" + driver + ", scores=" + Arrays.toString(scores) + "]";
    }

    public String getName() {
        return name;
    }

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

    public CarDriver getDriver() {
        return driver;
    }

    public void setDriver(CarDriver driver) {
        this.driver = driver;
    }

    public int[] getScores() {
        return scores;
    }

    public void setScores(int[] scores) {
        this.scores = scores;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

дорога Hа Cевер

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值