Cloneable接口和深拷贝

在java中如何对对象进行拷贝呢?我们可以使用Object类中的clone方法。

一、浅拷贝

在使用clone方法对对象进行拷贝的时候,需要注意:

1.需要重写clone方法;

2.clone方法的返回值是Object类,需要强制类型转化;

3.使用clone方法必须先实现Cloneable接口

复制代码
//深克隆
public class Test {
    //对抛出的异常进行处理
    public static void main(String[] args)throws CloneNotSupportedException {
         Person person=new Person("zhangsan",10);
         Person person1=(Person)person.clone();

         System.out.println("修改前:"+person.m.money);
         System.out.println("修改前:"+person1.m.money);

         person1.m.money=99.9;
        System.out.println("修改后:"+person.m.money);
        System.out.println("修改后:"+person1.m.money);
        //对person1.m.money修改后,person.m.money也被修改
    }
}
class Money {
    public double money=9.9;
}
//想要进行拷贝的类必须实现Cloneable接口
@SuppressWarnings("ALL")
class Person implements Cloneable{
    public int age;
    public String name;

    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    Money m=new Money();

    @Override
    public String toString() {
        return "Person{" +
               "age=" + age +
               ", name='" + name + '\'' +
                '}';
    }
    //重写clone方法
    protected Object clone()throws CloneNotSupportedException{
        return super.clone();
    }
}

运行结果:

可以看到当我们将person1.m.money修改为99.9是, person.m.money也被修改为99.9,这是为什么呢?

原因是我们只对person 进行了拷贝,而没有对m进行拷贝,因此person1和person中的m为同一个引用,它们指向同一个对象,像这种不完全的拷贝方式叫做浅拷贝。

二、深拷贝

如果想将上面的对象m也拷贝一份,也很简单,与拷贝person类似。

复制代码
//深克隆
public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Person person=new Person("zhangsan",10);
        Person person1=(Person)person.clone();

        System.out.println("修改前:"+person.m.money);
        System.out.println("修改前:"+person1.m.money);

        person1.m.money=99.9;
        System.out.println("修改后:"+person.m.money);
        System.out.println("修改后:"+person1.m.money);
    }
}
//Money类也实现Cloneable接口,对clone方法进行重写
class Money implements Cloneable{
    public double money=9.9;
    protected Object clone()throws CloneNotSupportedException{
        return super.clone();
    }
}
//想要进行拷贝的类必须实现Cloneable接口
@SuppressWarnings("ALL")
class Person implements Cloneable{
    public int age;
    public String name;

    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    Money m=new Money();

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    protected Object clone()throws CloneNotSupportedException{
        //clone的返回值为Object类,因此需要强制类型转换
        Person tmp=(Person) super.clone();
        //调用Monmey类中重写的clone方法,对m进行拷贝
        tmp.m=(Money) this.m.clone();
        return tmp;
    }
}

运行结果:

相关推荐
梵刹古音2 分钟前
【C语言】 格式控制符与输入输出函数
c语言·开发语言·嵌入式
Acrelhuang8 分钟前
工商业用电成本高?安科瑞液冷储能一体机一站式解供能难题-安科瑞黄安南
大数据·开发语言·人工智能·物联网·安全
hello 早上好9 分钟前
03_JVM(Java Virtual Machine)的生命周期
java·开发语言·jvm
沐雪架构师10 分钟前
LangChain 1.0 Agent开发实战指南
开发语言·javascript·langchain
tod11311 分钟前
力扣高频 SQL 50 题阶段总结(四)
开发语言·数据库·sql·算法·leetcode
2501_9400078922 分钟前
Flutter for OpenHarmony三国杀攻略App实战 - 战绩记录功能实现
开发语言·javascript·flutter
naruto_lnq22 分钟前
C++中的桥接模式
开发语言·c++·算法
无限进步_23 分钟前
面试题 02.02. 返回倒数第 k 个节点 - 题解与详细分析
c语言·开发语言·数据结构·git·链表·github·visual studio
夕除27 分钟前
js--7
java
布谷歌32 分钟前
面试题整理
java·开发语言