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 分钟前
Rspack:字节跳动自研 Web 构建工具-基于 Rust打造高性能前端工具链
开发语言·前端·javascript·rust·开源
Petrichorzncu2 分钟前
Lua再学习
开发语言·学习·lua
AA-代码批发V哥3 分钟前
正则表达式: 从基础到进阶的语法指南
java·开发语言·javascript·python·正则表达式
字节高级特工7 分钟前
【C++】”如虎添翼“:模板初阶
java·c语言·前端·javascript·c++·学习·算法
晴天下小雨o11 分钟前
排序算法总结
java·算法·排序算法
曼岛_14 分钟前
[Java实战]Spring Boot 整合 Redis(十八)
java·spring boot·redis
向哆哆31 分钟前
Netty在Java网络编程中的应用:实现高性能的异步通信
java·网络·php
炯哈哈37 分钟前
【上位机——MFC】序列化机制
开发语言·c++·mfc·上位机
程序员爱钓鱼40 分钟前
循环语句:for、range -《Go语言实战指南》
java·数据结构·算法
蓝莓味柯基42 分钟前
Python3正则表达式:字符串魔法师的指南[特殊字符]‍♂️
开发语言·python·正则表达式