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;
    }
}

运行结果:

相关推荐
Frank_refuel3 分钟前
【C++项目】手撕JRpc框架(单机怎么优化到分布式思想)
开发语言·c++
卓怡学长5 分钟前
w192基于springboot“考研情报站”微信小程序设计与实现
java·spring boot·spring·微信小程序·intellij-idea
wuminyu16 分钟前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++
可乐鸡翅yeah_21 分钟前
fmp4 碎片 MP4 格式 HLS 流,和传统 TS 分片有什么不一样
开发语言·javascript·ios·音视频·safari·m3u8·m3u8在线播放
流形填表23 分钟前
多校区题库标准化:Excel模板与校验脚本
开发语言·python
步行cgn32 分钟前
AOP 通知的类型详解
开发语言
weixin_3077791335 分钟前
从“人操作仪器”到“Agent 自主发现”:OPL 金属材料自驱动实验室 MVP 技术论述
开发语言·人工智能·算法·架构
笑鸿的学习笔记1 小时前
C++笔记之SIMD与SSE指令集
开发语言·c++·笔记
anew___1 小时前
《从零手写操作系统 (20):ELF加载器——让OS读懂现代编译器》
java·服务器·前端
code2cat1 小时前
【随笔】MCP资源更新订阅:通知到达以后,Agent怎样刷新旧资料
java·后端·开发工具·ai agent·mcp