Java代码实现—深拷贝与浅拷贝

目录​​​​​​​

1、Clonable 接口

 2、浅拷贝

3、深拷贝


1、Clonable 接口

  • Java 中内置了一些很有用的接口, Clonable 就是其中之一;
  • Object 类中存在一个 clone 方法,调用这个方法可以创建一个对象的 "拷贝",但是要想合法调用 clone 方法,必须要先实现 Clonable 接口,否则就会抛出 CloneNotSupportedException 异常。
  • 代码如下:
class Person implements Cloneable{
    public int age=20;


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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person person = new Person();
        Person person1=  (Person) person.clone();
        //person1.age = 99;


    }

}

1、这个类实现Cloneable这个接口,这个接口中是没有抽象方法的,所以叫做空接口,这里只证明Person这个类是可以被克隆的没有<>,不用传入类型。

2、如果想要克隆对象,要重写clone方法,他的父类是Object类,所以用super可以调用,generate生成或者crl+o可以自动生成,不用改变。

 3、

  • 建立一个Pesron的对象person,想要克隆person这个对象中的内容(也就是建立一个age的副本一样) 
  • 这时候Person这个类中就有clone方法了,可以直接用对象.调用,因为clone方法返回是Object类型,我们要Person类型,所以用强制类型转换。 

 2、浅拷贝

以下的深拷贝和浅拷贝的讨论都基于以下的代码,创建:

class Money implements Cloneable {
    public double money=19.9;

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

class Person implements Cloneable{
    public int age=10;
    public Money m = new Money();

   //浅拷贝的重写
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}


public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2 = (Person) person.clone();
        System.out.println(person.m.money);
        System.out.println(person2.m.money);

        person.m.money = 90.0;
        System.out.println(person.m.money);
        System.out.println(person2.m.money);
    }



}

1、建立了一个person2 克隆了一个person中的对象,但是对象中引用m所指向的对象money没有被拷贝,也就是两个m指向了同一个空间。

 

(2)这时候我们改动一个person.m.money的值,两个对象中的money都改变了,这就是浅拷贝 

       浅拷贝:拷贝了对象,但是没有拷贝对象中引用m所指向的对象money

3、深拷贝

  • 我们想实现的是,不光拷贝了person中的对象,也将m所指向的对象money也拷贝了一份,并将新的地址赋给m。 
  • 这时改变person2.m.money的值,person中的money的值不会改变

1、实现代码:

class Money implements Cloneable {
    public double money=19.9;

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

class Person implements Cloneable{
    public int age=10;
    public Money m = new Money();

    //深拷贝的重写
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp =(Person) super.clone();
        tmp.m = (Money) this.m.clone();
        return tmp;
    }


    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}


public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person2 = (Person) person.clone();
        System.out.println(person.m.money);
        System.out.println(person2.m.money);

        person.m.money = 90.0;
        System.out.println(person.m.money);
        System.out.println(person2.m.money);
    }



}

2、对于Money这个类的克隆方法需要重写,目的是可以克隆money这个对象,记得Money这个类要实现Cloneable这个接口。 

2、在Person中:

  • 首先第一行是克隆一份person就是age和m,给到tmp变量;
  • 第二行是克隆一份money,并将money的地址返回给tmp中的m(tmp我们是临时变量); 
  • 第三行是返回tmp的值,这里面是person2来接收了,并且tmp这个局部变量会销毁。

 

 3、深拷贝中,因为money也被拷贝了一份,而且地址和person中的地址不同,所以我们改变person2中money的值,不会影响到person中money的值,这就是深拷贝。

 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值