Clonable 接口和深拷贝

2023-12-21

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”.
在这里插入图片描述

想用clone方法时报错了,查看一下:
在这里插入图片描述

  • clone方法被protected修饰.不同包只能在子类中访问,可以用super关键字访问
  • clone方法返回类型是Object,所以需要向下转型
  • CloneNotSupportedException是受查异常,所以调用它的方法不处理就要throws,main方法不处理就交给JVM处理了

改良的代码

class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三");
        Person person2 = (Person)person1.clone();
        System.out.println(person2.name);
    }
}

但还是会报错
在这里插入图片描述
要想合法调用 clone 方法, 必须先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常,而它是空的,没有需要重写的方法
在这里插入图片描述
如果一个类实现了这个空接口/标记接口,那么证明当前类是可以被克隆的

class Person implements Cloneable{
    public String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三");
        Person person2 = (Person)person1.clone();
        System.out.println(person2.name);
    }
}

在这里插入图片描述
可以用try-catch进行处理,这样就不必用throws将异常报告给抛出异常方法的调用者

class Person implements Cloneable {
    public String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public Person clone() {
        Person person = null;
        try {
            person = (Person) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return person;
    }
}
public class Test {
    public static void main(String[] args) {
        Person person = new Person("张三");
        Person person2 = person.clone();
        System.out.println(person2.name);
    }
}

在这里插入图片描述

浅拷贝和深拷贝

Cloneable 拷贝出的对象是一份 “浅拷贝”

class Money {
    public double money = 13;
}
class Person implements Cloneable{
    public String name;
    public Money m;

    public Person(String name) {
        this.name = name;
        m = new Money();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三");
        Person person2 = (Person)person1.clone();
        System.out.println("修改之前:"+person1.m.money);
        System.out.println("修改之前:"+person2.m.money);

        person2.m.money = 99;
        
        System.out.println("修改之后:"+person1.m.money);
        System.out.println("修改之后:"+person2.m.money);
    }
}

在这里插入图片描述

我们只修改了person2 的money,但person1的money也被改成了99.

内存分布大致是这样的
假设0x56,0x87指向引用地址的对象

在这里插入图片描述
我们可以看到,通过clone,我们只是拷贝了Person对象。但是Person对象中的Money对象并
没有拷贝。通过person2这个引用修改了m的值后,person1这个引用访问m的时候,值也发生了改变。这里就是发生了 浅拷贝
改完后person1和person2还是指向同一个m,因为改变基本数据类型不会创建新的对象.

深拷贝 是克隆出一个完全独立于原来对象的对象(如果类中有基本数据类型那就进行拷贝)

代码如下:

class Money implements Cloneable{
    public double money = 13;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public Money m;

    public Person(String name) {
        this.name = name;
        m = new Money();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m = (Money)this.m.clone();
        return tmp;
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三");
        Person person2 = (Person)person1.clone();
        System.out.println("修改之前:"+person1.m.money);
        System.out.println("修改之前:"+person2.m.money);

        person2.m.money = 99;

        System.out.println("修改之后:"+person1.m.money);
        System.out.println("修改之后:"+person2.m.money);
    }
}

在这里插入图片描述
在这里插入图片描述
是不是深拷贝,就看程序猿实现的方式怎么样

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clonable 接口和深拷贝 的相关文章

  • 如何使用固定数量的工作线程实现简单线程

    我正在寻找最简单 最直接的方法来实现以下内容 主程序实例化worker 执行任务的线程 Only n任务可以同时运行 When n已达到 不再有工人 开始直到计数 正在运行的线程回落到下方n 我觉得Executors newFixedThr
  • 如果列名不同,则一对多休眠连接

    我有三个具有以下结构的表 合同 gt Contract id 主要 customer company id Vendor company id 公司 gt Company id 主要 创建日期 创建者 Company Timeline gt
  • 将一种类型的对象声明为另一种类型的实例有什么好处? [复制]

    这个问题在这里已经有答案了 可能的重复 Base b2 new Child 是什么意思 表示 https stackoverflow com questions 4447924 what does base b2 new child sig
  • 如何配置 Spring-WS 以使用 JAXB Marshaller?

    感谢您到目前为止对此的帮助 我正在更新问题 因为我没有显示我需要的所有内容 并显示了建议的更改 肥皂输出仍然不是我想要的 servlet xml
  • 在命令行java中突出显示文本[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一项任务是重新创建 unix cal 程序 除了一部分之外 相当简单 今天 它突出显示了该数字 我不知道该怎么做 关于如何在 Ja
  • 在 Java 中从 SOAPMessage 获取原始 XML

    我已经在 J AX WS 中设置了 SOAP WebServiceProvider 但我无法弄清楚如何从 SOAPMessage 或任何 Node 对象获取原始 XML 下面是我现在获得的代码示例 以及我试图获取 XML 的位置 WebSe
  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • javax.persistence.RollbackException:提交事务时出错],根本原因是 java.lang.StackOverflowError:null

    我有一个使用 Spring Data REST 框架的 Spring Boot API 从 spring boot starter parent 2 1 0 RELEASE 继承的依赖项 我正在尝试执行 PUT 或 PATCH 请求来更新实
  • 如何为小程序提供对文件系统写入的访问权限

    我在设置小程序的策略文件时遇到问题 我是第一次这样做 不知道如何在java中设置小程序的策略文件 实际上我想授予小程序在文件系统上写入的权限 为此我必须向小程序授予文件权限 所以我创建了一个名为 java policy 的文件 并将以下代码
  • 使用 JSch 分别为各个提示提供输入

    问题是 SSH 连接需要在常规登录后提供另一个用户 ID 和密码信息 我正在使用 JSch 连接到远程服务器 它接受以下形式的输入InputStream 和这个InputStream只能通过一次 由于会话是交互式的 这会导致问题 我尝试将输
  • OpenNLP 与斯坦福 CoreNLP

    我一直在对这两个包进行一些比较 但不确定该往哪个方向走 我简单地寻找的是 命名实体识别 人 地点 组织等 性别识别 一个不错的训练 API 据我所知 OpenNLP 和斯坦福 CoreNLP 提供了非常相似的功能 然而 Stanford C
  • 使用 JAX-WS 的 WebLogic 中没有模式导入的单个 WSDL

    如何使用 JAX WS 配置由 WebLogic 10 3 6 生成的 Web 服务 以将对象架构包含在单个 WSDL 文件声明 而不是导入声明 中 示例代码 界面 import javax ejb Local Local public i
  • 如何使用 swagger-codegen-plugin (maven) 生成客户端代码?

    我需要使用 swagger codegen plugin for maven 在 eclipse 中生成服务器存根代码 你能帮忙怎么做吗 以及需要什么配置 在 pom xml 中 我找到了这个答案 您只需要像下面这样更改 pom xml 即
  • Android 解析 JSON 卡在 get 任务上

    我正在尝试解析一些 JSON 数据 我的代码工作了一段时间 我不确定我改变了什么突然破坏了代码 当我运行代码时 我没有收到任何运行时错误或警告 我创建一个新的 AsyncTask 并执行它 当我打电话时 get 在这个新任务中 调试器在此行
  • java swing:向 JTree 项目添加自定义图形按钮

    我想在 JTree 中的项目右侧添加一个带有小图标的附加按钮 这可以做到吗 如果是这样 怎么办 thanks Clamp 你在这方面成功了吗 我想做同样的事情 但很难让 JButton 响应用户 设置渲染器以显示按钮的过程很顺利 但所有鼠标
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • 如何清理 Runtime.exec() 中使用的用户输入?

    我需要通过命令行调用自定义脚本 这些脚本需要很少的参数并在 Linux 机器上调用 当前版本容易出现各种shell注入 如何清理用户给出的参数 参数包括登录名和路径 Unix 或 Windows 路径 用户应该能够输入任何可能的路径 该路径
  • 使用自定义比较器在 Java 中创建 SortedMap

    我想创建一个TreeMap在 Java 中具有自定义排序顺序 排序后的键是字符串 需要根据第二个字符进行排序 这些值也是字符串 示例地图 Za FOO Ab Bar 您可以像这样使用自定义比较器 Comparator
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m
  • 将数组值导出到 csv 文件 java

    我只需要帮助将数组元素导出到 csv 文件 我不知道我的代码有什么问题 任何帮助将不胜感激 谢谢 for int index 0 index lt cols length index FileWriter fw new FileWriter

随机推荐

  • 职言|三年功能测试,一些测试工作的“吐槽”

    概述 社区里大部分都是测试开发的分享 作为功能测试 我也分享下日常工作中功能测试值得吐槽的问题 由于工作时间不长且未进过大厂 不了解大公司的工作模式和流程 所以自己的方法和理解都是基于中小公司的工作经验总结 应该适用于跟我一样的小白 没有各
  • 用RPA轻松实现金蝶值班收款,提升工作效率!

    在财务领域 值班收款是一个重复 耗时 操作琐碎且容易出错的工作 传统的值班收款方式通常需要人工进行电脑操作 包括登录金蝶系统 录入收款信息 生成凭证等 这些操作不仅浪费时间和人力资源 还存在人为错误的风险 可能导致财务数据的不准确和凭证的错
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • 技术博客:市面上加密混淆软件的比较和推荐

    引言 市面上有许多加密混淆软件可供开发者使用 但哪些软件是最好用的 哪些软件受到开发者的喜爱 本文将根据一次在CSDN上的投票结果 为大家介绍几款在程序员中普及度较高的加密软件 以下是投票结果 希望能对大家的选择提供参考 正文 第一款 ip
  • C 语言运算符详解

    C 语言中的运算符 运算符用于对变量和值进行操作 在下面的示例中 我们使用 运算符将两个值相加 int myNum 100 50 虽然 运算符通常用于将两个值相加 就像上面的示例一样 它还可以用于将变量和值相加 或者将变量和另一个变量相加
  • wksprtPS.dll文件缺少导致程序无法启动问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个wksprtP
  • 揭开神秘面纱,探索犹格索托斯的庭院:一款令人陶醉的模拟经营+AVG游戏

    你是否曾梦想过踏入一个充满神秘与奇幻的世界 体验一番独特的冒险 现在 这个梦想将成为现实 我们荣幸地向你介绍一款全新的模拟经营 AVG游戏 犹格索托斯的庭院 犹格索托斯的庭院是一款极具创意的游戏 它将带你进入一个神秘而充满魅力的世界 在这里
  • Axure RP 8 for Mac/win中文版:打造完美交互式原型设计体验

    Axure RP 8 一款引领潮流的交互式原型设计工具 为设计师提供了无限的可能性 让他们能够创造出逼真的原型 从而更好地展示和测试他们的设计 Axure RP 8拥有丰富的功能和工具 让设计师可以轻松地创建出复杂的交互式原型 从简单的按钮
  • Spring Cloud+SpringBoot b2b2c:Java商城实现一件代发设置及多商家直播带货商城 免 费 搭 建

    saas云平台 打造全行业全渠道全场景的saas产品 为经营场景提供一体化解决方案 门店经营区域化 网店经营一体化 本地化 全方位 一站式服务 为多门店提供统一运营解决方案 提供丰富多样的营销玩法覆盖所有经营场景 助力商家成功 系统稳定压倒
  • 如何用CHAT写岗位职责概述?

    问CHAT 请写份技术部服务端组长岗位概述及工作内容 CHAT回复 技术部服务端组长主要负责带领服务端技术团队开发 测试和优化公司的服务端系统和平台 由于他们的工作直接影响到产品或服务的运行效能和稳定性 因此他们必须拥有丰富的技术知识和经验
  • 企业办公楼:你一定要知道的门禁管理技巧!

    随着科技的不断发展 门禁监控系统在各行各业中变得越来越重要 这一技术不仅提供了对建筑物和区域的安全控制 还为管理人员提供了实时的监测和数据分析工具 客户案例 企业办公楼 广州某大型企业面临着员工进出办公楼的管理难题 传统的门禁系统已经无法满
  • winrsmgr.dll文件缺少导致程序无法运行问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个winrsmg
  • 康奈尔笔记法:高效学习的秘密武器

    在求知的道路上 我们常常会遇到这样的情况 上课时明明听得很认真 但课后却发现自己对知识的掌握并不牢固 阅读书籍时 尽管我们做了很多笔记 但最后却发现自己并没有真正理解 这就是因为没有找到有效的学习方法 而康奈尔笔记法 就是一种能够帮助我们高
  • 京东岗位吼哔多,具体有啥牛牛说!5类方向近20个岗位等你选~

    字节 测试开发 日常实习 三面面经 已发offer 字节测开秋招面经 华为上海青浦研究所现状 而我 落荒而逃 得物实习小记 运营岗位爆料 干了5年运营后我才知道的事 华为海思麒麟开奖清蒸白菜新鲜出炉 真的难啊 华为上海青浦研究所现状 华为上
  • 京东岗位吼哔多,具体有啥牛牛说!5类方向近20个岗位等你选~

    字节 测试开发 日常实习 三面面经 已发offer 字节测开秋招面经 华为上海青浦研究所现状 而我 落荒而逃 得物实习小记 运营岗位爆料 干了5年运营后我才知道的事 华为海思麒麟开奖清蒸白菜新鲜出炉 真的难啊 华为上海青浦研究所现状 华为上
  • 短视频时代:文案的力量与价值

    在当今这个信息时代 短视频以其独特的魅力和巨大的传播力 已经深深地渗透到我们的生活中 无论是抖音 快手 还是其他短视频平台 它们都在以自己独特的方式塑造着我们的娱乐生活 而在这些短片的背后 有一个重要的元素在发挥着关键的作用 那就是文案 文
  • Oracle EBS 暂挂发票放弃行按钮为灰色

    Oracle EBS 暂挂发票放弃行按钮为灰色 解决办法如下 应付设置职责下 设置 选项 应付款系统选项 找到发票页签 将 允许对已付发票进行调整 勾选后 回到发票界面重新查询发票 暂挂发票放弃行按钮正常操作 To allow the li
  • SAP ERP系统怎么样?适合中小企业吗?

    SAP是什么 它跟ERP什么关系 对于工业4 0 能起到什么作用 哪里有SAP最新的资讯 我们先来对这两个名词做一个简单的解释 SAP 思爱普 是全球领先的业务流程管理软件供应商之一 致力于开发先进的解决方案 帮助企业高效处理整个企业范围内
  • 博睿数据参与支持2023年度证券期货业标准研究课题获评“优秀”

    近期 全国金融标准化技术委员会证券分技术委员会发布 关于公布2023年度证券期货业标准研究课题结题评审结果的通知 由西南证券独立申报 博睿数据提供系统支持的课题 证券期货业移动互联网应用程序性能指标及检测模型研究 在2023年度证券期货业标
  • Clonable 接口和深拷贝

    Object 类中存在一个 clone 方法 调用这个方法可以创建一个对象的 拷贝 想用clone方法时报错了 查看一下 clone方法被protected修饰 不同包只能在子类中访问 可以用super关键字访问 clone方法返回类型是O