Java深拷贝和浅拷贝,Cloneable接口

Java - 对象克隆、Cloneable接口、浅克隆和深克隆 本文总结了Java中的Cloneable接口的作用及其使用方式,以及Java创建对象的四种方式。Cloneable接口是一个标记接口,实现它并重写Object中的clone方法才能成功克隆对象。Object的clone方法是浅拷贝,如果要执行深拷贝,需要按需重写clone方法。Java创建对象的方式包括new、clone、输入输出流和反射构造对象等。此外,本文还介绍了浅克隆和深克隆的概念和示例代码,并解释了为什么需要实现Cloneable接口才能实现深克隆。 阅读详情

1. Cloneable接口的介绍

Cloneable是标记型的接口(空接口),它们内部都没有方法和属性, 实现 Cloneable来表示该对象能被克隆 ,能使用Object.clone()方法。如果没有实现 Cloneable的类对象调用clone()就会抛出CloneNotSupportedException异常。

可以理解为Cloneable接口发挥的是标记功能,自定义类型需要用户自己标记出哪些类是可以clone的,这个标记就是去实现Cloneable接口,实现了Cloneable接口后就表明该类创建的对象可以被克隆。

而要想使一个类具备拷贝实例的功能,除了要实现Cloneable接口,还必须重写Object类的clone()方法。

可以看到Object类的clone()方法是被protected修饰的,所以需要在重写的clone()方法中通过super关键字去调用Object类中的clone()方法

2. 浅拷贝的介绍和实例

在拷贝一个对象时,对 对象的基本数据类型的成员变量进行拷贝,但对引用类型的成员变量只进行引用的传递,并没有创建一个新的对象, 当对引用类型的内容修改会影响被拷贝的对象 。简而言之: 浅拷贝仅仅复制所拷贝的对象,而不复制它所引用的对象。

观察下面的代码,将Money类的实例作为了Person类的字段,new一个Person类的对象person1,将这个person1对象拷贝到person2中,这里的拷贝就是浅拷贝了,只是将person1对象的money引用拷贝到了person2,person1和person2中的momey指向的是同一个对象。

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">class  Money  { 
    public double m = 666;
}
class  Person  implements  Cloneable{ 
    int id;
    public Money money = new Money();

    public  Person(int id)  { 
        this.id = id;
    }

    @Override
    protected  Object  clone()  throws  CloneNotSupportedException  { 
        return super.clone();
    }

    @Override
    public  String  toString()  { 
        return "Person{" +
                "id=" + id +
                ", money=" + money.m +
                '}';
    }
}
public class  TestDemo3  { 
    public  static  void  main(String[] args)  throws  CloneNotSupportedException  { 
        Person person1 = new Person(1);
        Person person2 = (Person) person1.clone();

        System.out.println("通过person2修改前的结果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通过person2修改后的结果");
        System.out.println(person1);
        System.out.println(person2);
    }
}

执行结果:

浅拷贝图解:

3. 深拷贝的介绍和实例

在拷贝一个对象时,除了对基本数据类型的成员变量进行拷贝,对引用类型的成员变量进行拷贝时,创建一个新的对象来保存引用类型的成员变量。简而言之: 深拷贝把要复制的对象所引用的对象都复制了一遍。

下面的代码实现了深拷贝;实现person1对象的深拷贝,先用Person tmp引用来保存浅拷贝的结果,通过tmp引用找到money对象,再将money对象拷贝一份,然后赋值给tmp中的money,最后返回tmp即可。这样就将money引用的对象也拷贝了一份,实现了深拷贝,此时person1和person2中的momey指向的是两个不同的对象。

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">class  Money  implements  Cloneable{ 
    public double m = 666;

    @Override
    protected  Object  clone()  throws  CloneNotSupportedException  { 
        return super.clone();
    }

}

class  Person  implements  Cloneable{ 
    public int id;
    public Money money = new Money();

    public  Person(int id)  { 
        this.id = id;
    }

    @Override
    protected  Object  clone()  throws  CloneNotSupportedException  { 
        //return super.clone();
        Person tmp = (Person) super.clone();
        tmp.money = (Money) this.money.clone();
        return tmp;
    }

    @Override
    public  String  toString()  { 
        return "Person{" +
                "id=" + id +
                ", money=" + money.m +
                '}';
    }
}
public class  Test2  { 
    public  static  void  main(String[] args)  throws  CloneNotSupportedException{ 
        Person person1 = new Person(1);
        Person person2 = (Person) person1.clone();

        System.out.println("通过person2修改前的结果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通过person2修改后的结果");
        System.out.println(person1);
        System.out.println(person2);
    }
}

执行结果:

深拷贝图解:

4. clone方法总结

java中clone方法是一个浅拷贝,引用类型依然在传递引用。我们可以通过继续调用clone()方法,对 该对象的引用类型变量再实现一次clone()的方法来实现深拷贝。

关于 Cloneable 接口 和 重写 Object.clone() 方法的尝试顺便复习深拷贝和浅拷贝 一个类如果想重写 Object 的 clone 方法,则必须实现 Cloneable 接口,否则调用 clone 方法时将会抛出 CloneNotSupportException 异常 /** * Author: heatdeath * Date: 2018/7/7 * Desc: */ public class CloneDemo { static class Clon... 阅读详情

相关推荐

深入理解Java中的Comparable、Comparator和Cloneable接口

Java是一门面向对象编程语言,它通过接口提供了多种机制来增强类的功能。本文将详细介绍Java中的三个重要接口:Comparable、Comparator和Cloneable,重点讨论它们的用途、实现和最佳实践。此外,我们还将深入探讨浅拷贝与深拷贝的概念及其在实际应用中的重要性。

fudaihb的博客 1321

你真的懂Java中的Cloneable接口和深拷贝么?

全网最细深拷贝讲解

Shine0115的博客 1562

GD32F303 ADC+DMA实战:用硬件过采样搞定多通道数据采集(附完整代码)

本文详细介绍了GD32F303系列MCU通过ADC+DMA结合硬件过采样技术实现多通道数据采集的实战方案。从硬件设计要点到软件配置全解析,包括时钟树配置、ADC模块初始化和DMA传输设置,提供了完整的代码示例和优化技巧,帮助工程师构建高精度、低功耗的数据采集系统。

weixin_30466039的博客 318

【Java】深拷贝和浅拷贝,Cloneable接口

深拷贝和浅拷贝介绍和区分,Cloneable接口介绍及clone方法的使用。

trong_ 的烂笔头 4141

HDMI设计6--Video PHY Controller IP

Reference:https://china.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/vid_phy_controller/v2_2/pg230-vid-phy-controller.pdf 1. 序 Video PHY Controller IP是为实现与视频(DisplayPort和HDMI™技术)MAC传输或接收子系统的即插即用连接而设计的。视频MAC层和PHY层的接口是标准化的,能...

Archar_Saber的博客 8338

zabbix 监控EMC存储

经过搜索,找到了脚本地址,该项目应该是模板原作者创建的,该项目也有zabbix模板,和上面的应该是相同的,我用的是上面的模板。./unity_get_state.py --api_ip='X.X.X.X' --api_port='443' --api_user='zabbix' --api_password='PASSWORD' --storage_name="zabbix web前端配置的主机名" --discovery。修改权限,给zabbix用户执行权限,模板调用时以zabbix用户执行。

wangyfde的专栏 3753

Java-cloneable方法介绍

在Java中,Cloneable是一个标记接口,用于指示类实现了克隆(clone)功能。当一个类实现了Cloneable接口,则表示该类的实例可以被复制。该接口没有任何方法,只是作为一个标记,告诉编译器这个类可以被克隆。

架构师之路。。 1463

用Multisim和74192芯片复刻经典:手把手教你搭建篮球24秒违例计时器(附仿真文件)

本文详细介绍了如何使用Multisim仿真平台和74192芯片构建篮球24秒违例计时器,涵盖时序逻辑电路设计、核心器件选型、仿真环境搭建及调试技巧。通过分步指导,帮助读者掌握数字电路设计的关键技术,并附赠仿真文件供实践参考。

weixin_27014595的博客 277

【Java SE】 Cloneable接口, 浅拷贝和深拷贝

目录Cloneable接口浅拷贝深拷贝 什么叫对象的拷贝? 或者克隆? 就是把这个对象完完整整的复制一份出来,两份对象是一模一样的,比双胞胎还双胞胎,那怎么样实现呢? public static void main(String[] args) { Person person1 = new Person("zhangsan", 18); Person person2 = new Person("zhangsan", 18); } 我们发现,这种写法,new出来的两个对象也是一模一样

qq_59877583的博客 957

2025软考信息安全工程师真题

2025信息安全工程师软考真题

qq_40424393的博客 1706

还在用iReport 5.6.0?手把手教你用JasperSoft Studio 6.8.0设计报表(附JDK 11+兼容方案)

本文详细介绍了从iReport 5.6.0迁移到JasperSoft Studio 6.8.0的全过程,包括JDK 11+环境配置、项目迁移实战、高级特性应用及常见问题解决方案。帮助开发者高效完成报表生成工具的升级,提升开发体验和报表性能。

weixin_30687051的博客 407

java的Cloneable接口和浅拷贝与深拷贝

文章目录简介浅拷贝深拷贝 简介 Cloneable接口是java.lang包下的接口,Cloneable其实是一个标记接口,只在实现这个接口后,我们才能重写object类中的clone()方法。clone也是首先分配内存,这里分配的内存与调用clone方法对象的内存相同,然后将源对象中各个变量的值,填充到新的对象中,填充完成后,clone方法返回一个新的地址,这个新地址的对象与源对象相同,只是地址不同。 浅拷贝 class Money implements Cloneable{ public dou

m0_62476684的博客 770

Android车载蓝牙开发全攻略:从基础到高级优化

本文系统介绍了Android车载蓝牙开发的核心技术与实践指南。文章首先阐述了蓝牙在智能汽车中的关键作用,包括免提通话、音频流媒体等应用场景。随后详细解析了蓝牙协议基础,重点介绍了HFP、A2DP等车载常用协议。开发实战部分提供了设备发现、连接、数据传输的完整代码示例,并融入多线程和内存优化技巧。通过真实车载案例,展示了启动时间、流畅度和资源使用的优化策略。最后针对面试需求,提供了专业的技术问答,涵盖蓝牙开发全流程。全文紧密结合Android车载开发职位要求,为开发者提供了一套完整的蓝牙技术解决方案。

郑伟强dev的专栏 116

【Java】Cloneable接口的浅拷贝和深拷贝/克隆

Java中Object类中的clone方法可以创建一个对象的拷贝,要调用clone方法,就要先实现Java内置的接口Cloneable如: 接下来看看克隆的简单应用:创建Goods类,表示货物,新建对象为book书 在创建新对象后,通过调用clone进行了拷贝: 输出为: 这里要注意,在调用clone方法时,clone是父类Object的方法,所以克隆得到的对象类型是Object类,再此要将克隆结果赋给book2的话,就要将对象的类型强制转换为Goods接下来我们再创建一个Storage类,代表

m0_57680308的博客 782

Python爬虫实战:基于Scrapy与Playwright高效爬取人民网新闻数据

本文将详细介绍如何使用Python最新技术栈(Scrapy框架结合Playwright浏览器自动化工具)高效爬取人民网新闻数据。文章包含完整项目搭建、反反爬策略、数据解析存储以及性能优化等核心内容,提供可直接运行的代码示例,适合中高级Python开发者学习现代网络爬虫开发技术。python# 去除特殊空白字符。

2201_76125261的博客 1118

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

java--Cloneable接口和浅拷贝深拷贝(详解)

本文详细介绍了什么是Cloneable接口,然后让大家更好的理解深拷贝和浅拷贝,快来和博主一起学习吧~~

2302_81090306的博客 1233

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

JAVA实现深拷贝浅拷贝_Java cloneable接口实现深拷贝和浅拷贝

深拷贝:完全开辟出一个新的对象浅拷贝:引用同一对象的地址浅拷贝实现://默认为浅克隆@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}深拷贝实现:@Overrideprotected Object clone() throws CloneNotSupportedExc...

weixin_33669766的博客 199

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java三大常用接口-----Comparable Comparator Cloneable(包含深拷贝和浅拷贝讲解)

前言 由于Comparable和Comparator密切相关,所以我们先介绍这两个接口! 文章目录1. 简述Comparable Comparator1.1 Comparable接口1.2 Comparator接口1.3 二者比较2.Cloneable接口2.1简述2.2克隆的分类2.3 克隆代码举例2.3.1浅拷贝2.3.2深拷贝 1. 简述Comparable Comparator Java中的排序是由Comparable和Comparator这两个接口来提供的。 Comparable表示可被排序的,

m0_60565784的博客 400

Java基础笔记之深拷贝与浅拷贝(protected && Cloneable)

深拷贝与浅拷贝、protected修饰符和Cloneable

qq_44136520的博客 452

Cloneable接口和对象的克隆——浅拷贝和深拷贝

由浅至深,层层剖析,Cloneable接口和对象的克隆——浅拷贝和深拷贝

ijj_zZ的博客 1272

Java中的深拷贝与浅拷贝

浅拷贝:对基本类型数据进行值传递,对引用类型数据进行引用传递的拷贝深拷贝:对基本类型数据进行值传递,对引用类型数据创建一个新的对象,并复制其内容在Java中,所有的对象都继承自,在类中提供了一个方法来供我们对Java对象进行拷贝: 这个方法是的,所以不需要我们来实现。不过需要注意的是,这个方法还是的,这意味着方法只在包或其子类可见。方法还抛出了一个异常,通过源码注释可以知道,当调用了方法的对象类没有实现接口,或者无法克隆对象的时候,会抛出该异常,也就是说,如果要成功的调用接口,首先该类要实现接口。 Clon

qq_43460095的博客 6742

浅拷贝和深拷贝

了解了深拷贝和浅拷贝的区别,并学会用内存图分析代码❤️❤️❤️❤️。

2302_80455544的博客 731

Java基础系列-浅拷贝和深拷贝

Java中的拷贝功能是由Object类的clone方法定义的。//...//...这是一个可被重写的本地方法。这个方法是与Cloneable接口相关联的,如果针对一个没有实现Cloneable接口的方法执行器clone方法,会抛出CloneNotSupportedException异常。

smart_an的专栏 953

在JAVA中Cloneable接口的使用以及什么是深拷贝、浅拷贝

一、首先我们来看一下为什么在JAVA中要进行拷贝数据 在Java中所有的对象都是保存在堆中,而堆是供全局共享的。也就是说,如果同一个Java程序的不同方法,只要能拿到某个对象的引用,引用者就可以随意的修改对象的内部数据(前提是这个对象的内部数据通过get/set方法曝露出来)。有的时候,我们编写的代码想让调用者只获得该对象的一个拷贝(也就是一个内容完全相同的对象,但是在内存中存在两个这样的对象)...

weixin_44151598的博客 693

如何实现Cloneable接口?深拷贝和浅拷贝的区别?

1.如何实现Cloneable接口?2. 什么是浅拷贝? 什么是深拷贝?

crazy_xieyi的博客 1009
上一篇: Hbase Java API原理介绍
下一篇: 那些你不知道的“反射”技术
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值