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

运行结果:

相关推荐
abcnull5 分钟前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡11 分钟前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手27 分钟前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan41 分钟前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_1800790547342 分钟前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路1 小时前
C++23概述
java·c++·c++23
时空系1 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
专注API从业者2 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
CHANG_THE_WORLD2 小时前
python 批量终止进程exe
开发语言·python
摇滚侠2 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql