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

运行结果:

相关推荐
努力学习的小廉8 分钟前
【C++】 —— 笔试刷题day_14
开发语言·c++
wenbin_java12 分钟前
设计模式之备忘录模式:对象状态的可逆时光机
java·设计模式·备忘录模式
fengwuJ19 分钟前
Idea忽略已提交文件
java·ide·git·intellij-idea·ignore
漫步企鹅23 分钟前
【GDB】调试程序的基本命令和用法(Qt程序为例)
开发语言·qt·gdb·调试
阿昆的科研日常33 分钟前
Matlab个性化绘图第10期—滑珠进度柱状图
开发语言·matlab·可视化·论文插图
斑驳的岁月33 分钟前
MacOs java环境配置+maven环境配置踩坑实录
java·macos·maven
严文文-Chris37 分钟前
方法区、堆、虚拟机栈、寄存器分别存储哪些内容?为什么存储这些内容?
java·开发语言
qq_4850152144 分钟前
Java网络编程干货
java·网络·php
无名之逆1 小时前
Hyperlane 文件分块上传服务端
服务器·开发语言·前端·网络·http·rust·php
努力的搬砖人.1 小时前
java爬虫案例
java·经验分享·后端