个人理解Java的浅克隆与深克隆

news2024/11/27 16:41:34

浅克隆

浅克隆只会克隆基本数据属性,而不会克隆引用其他对象的属性,String类型除外。(String对象是不可修改的对象,每次修改其实都是新建一个新的对象,而不是在原有的对象上修改,所以当修改String属性时其实是新开辟一个空间存储String对象,并把引用指向该内存,而克隆出来的对象的String属性还是指向原有的内存地址,所以String对象在浅克隆中也表现得与基本属性一样。)

如果你需要拷贝的对象只包含基本数据类型和String直接用浅克隆也没什么影响。

 

步骤

  1. 对象的类需要实现Cloneable接口
  2. 重写Object类中的clone()方法
  3. 根据重写的clone()方法得到想要的克隆结果

 示例:

public class Person  implements  Cloneable{
    private  int age ;
    private  String name;

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

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
 public static void main(String[] args) throws ClassNotFoundException, CloneNotSupportedException {
        Person person = new Person(11,"aa");
        Person newPerson  = person.clone();
        person.setAge(21);
        person.setName("bb");
        System.out.println(person.toString());
        System.out.println(newPerson.toString());
    }

 深克隆

深克隆会把原型对象和原型对象所引用的对象,都复制一份给克隆对象。原对象和克隆对象完全不搭噶(不搭噶:完全独立,没有关系。)

 实现方式

  1. 实现 Cloneable 接口并重写 Object 类中的 clone()
  2. 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆
  3. 通过第三方工具,如Gson、Jackson

优缺点 

深拷贝方法

优点

缺点

重写clone()方法

1. 底层实现较简单

2. 不需要引入第三方包

3. 系统开销小

1. 可用性较差,每次新增成员变量可能需要修改clone()方法

2. 拷贝类(包括其成员变量)需要实现Cloneable接口

Apache.Commons.Lang序列化

1. 可用性强,新增成员变量不需要修改拷贝方法

1. 底层实现较复杂

2. 需要引入Apache Commons Lang第三方JAR包

3. 拷贝类(包括其成员变量)需要实现Serializable接口

4. 序列化与反序列化存在一定的系统开销

Gson序列化

1. 可用性强,新增成员变量不需要修改拷贝方法

2. 对拷贝类没有要求,不需要实现额外接口和方法

1. 底层实现复杂

2. 需要引入Gson第三方JAR包

3. 序列化与反序列化存在一定的系统开销

Jackson序列化

1. 可用性强,新增成员变量不需要修改拷贝方法

1. 底层实现复杂

2. 需要引入Jackson第三方JAR包

3. 拷贝类(包括其成员变量)需要实现默认的无参构造函数

4. 序列化与反序列化存在一定的系统开销

 



public class Attribute implements  Cloneable{
    //战力值
    private  int  combatPowerValue;
    //防御值
    private  int  defenseValue;

    public Attribute(int combatPowerValue, int defenseValue) {
        this.combatPowerValue = combatPowerValue;
        this.defenseValue = defenseValue;
    }

    public int getCombatPowerValue() {
        return combatPowerValue;
    }

    public void setCombatPowerValue(int combatPowerValue) {
        this.combatPowerValue = combatPowerValue;
    }

    public int getDefenseValue() {
        return defenseValue;
    }

    public void setDefenseValue(int defenseValue) {
        this.defenseValue = defenseValue;
    }

    @Override
    public String toString() {
        return "Attribute{" +
                "combatPowerValue=" + combatPowerValue +
                ", defenseValue=" + defenseValue +
                '}';
    }

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


public class Person  implements  Cloneable{
    private  int age ;
    private  String name;
    private  Attribute attribute;

    public Person(int age, String name, Attribute attribute) {
        this.age = age;
        this.name = name;
        this.attribute = attribute;
    }

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Attribute getAttribute() {
        return attribute;
    }

    public void setAttribute(Attribute attribute) {
        this.attribute = attribute;
    }

    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person clone = (Person) super.clone();
        //如果有多个引用对象,需要每个对象都需要重新设置,不灵活。
        clone.setAttribute(this.attribute.clone());
        return clone;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", attribute=" + attribute +
                '}';
    }
}
   public static void main(String[] args) throws ClassNotFoundException, CloneNotSupportedException {
        Attribute attribute = new Attribute(1000, 200);
        Person person = new Person(11,"aa",attribute);
        Person newPerson  = person.clone();
        person.setAge(21);
        person.setName("bb");
        person.getAttribute().setCombatPowerValue(500);
        System.out.println(person.toString());
        System.out.println(newPerson.toString());
    }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/858544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2.7如何使用vue-i18n

版本: vue:2.7.0 vue-i18n:8.28.2 一、下载 npm i vue-i18n8.28.2二、新建 新建一个文件,例如:lang,项目结构如下: index.js: import Vue from vue import VueI18n from vue-i18n…

函数的递归

1、什么是递归? 程序调用自身的编程技巧称为递归。 递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解&#x…

最强自动化测试框架Playwright-操作指南(3)-PO模式

playwright支持PO模式 创建页面对象 class SearchPage:def __init__(self, page):self.page pageself.search_term_input page.get_by_role("searchbox", name"输入搜索词")def navigate(self):self.page.goto("https://bing.com")def searc…

《人脸识别技术应用安全管理规定(征求意见稿)》,需要关注三个焦点

目录 严防人脸信息采集与滥用 规范人脸识别信息的处理 保障人脸识别技术的安全 人脸识别主要有三类风险 近日,国家互联网信息办公室发布《人脸识别技术应用安全管理规定(试行)(征求意见稿)》公开征求意见的通知。 …

甄品焕新|燕千云服务请求预警功能上线,燕小千AIGC能力再升级

​ 燕千云数智化业务服务平台发布了1.23.0版本,此次版本上线了服务请求预警功能,增加呼叫中心服务场景中的通话质检功能,提高了企业IT服务效率。此次还升级了燕小千AIGC能力,不仅可以实时预估文档学习时间,还可以一键分…

multi-head_seft-attention(多头自注意力)

对比 相比于single-head,multi-head就是将 q i q^i qi分成了 h h h份 multi-head_seft-attention的计算过程 将 q i q^i qi分成了 h h h份 计算过程 对于每个Head,我们可以提取出他的 b 11 b_{11} b11​到 b m 1 b_{m1} bm1​,以 H e…

Spring 事务管理

目录 1. 事务管理 1.1. Spring框架的事务支持模型的优势 1.1.1. 全局事务 1.1.2. 本地事务 1.1.3. Spring框架的一致化编程模型 1.2. 了解Spring框架的事务抽象(Transaction Abstraction) 1.2.1. Hibernate 事务设置 1.3. 用事务同步资源 1.3.1…

第十四届中国大学生服务外包大赛圆满落幕,合合信息助力人才发展消除市场“信息差”

老年人存在记账难题,如何通过技术手段处理?已经上线多年的软件产品,如何优化才能更符合现代人群的“胃口”?这些微小却关键的问题颇具社会价值,青年学子们的参与或许能够打开新的产品构建维度。 近日,“中…

Golang struct 结构体指针类型 / 结构体值类型

struct类型的内存分配机制 结构体变量之间的赋值是值拷贝。 type stu struct {Name stringSlice []stringMap1 map[string]string }func main() {s : stu{}s.Slice make([]string, 6)s.Slice[1] "ssss"s.Slice[2] "xxxx"s.Map1 make(map[string]stri…

必备 | SQL语句的封装操作大全

在封装SQL语句之前,我们得知道什么是DAO封装与实体类以及JDBC工具类的封装与连接数据库的具体流程。 封装SQL语句的好处: 封装SQL语句后就可以导包,给其他的工程使用,大大降低开发的强度,减少代码的冗余。如何导包给…

MFC第二十九天 CView类的分支(以及其派生类的功能)、MFC六大关键技术

文章目录 CView类的分支CEditViewCHtmlViewMainFrm.h CMainFrame 类的接口CMainView .h CListCtrl与CListView的创建原理 CTreeViewCTreeCtrl类简介CTreeCtrl类的原理以及常用功能 MFC六大关键技术视图和带分割栏的框架开发与消息路由CLeftView.cppCRightView.hCRightView.cppC…

Linux入门级命令

目录 1、开启终端 2、Linux命令格式 3、扩展:Linux下的命令补全 4、切换用户 5、uname命令 6、ls命令 ☆ 用法一 ☆ 用法二 ☆ 用法三 7、pwd命令 8、cd命令 9、clear命令 10、reboot命令 11、shutdown命令 12、type命令 13、history命令 14、host…

【学习】若依源码(前后端分离版)之 “ 分页以及查询的功能实现”

大型纪录片:学习若依源码(前后端分离版)之 “ 分页以及查询的功能实现” 前端部分后端部分结语 包括代码生成也好,最原始的系统也好,若依里每个页面只要有数据,基本上就有分页的功能,所以理解分…

背上大书包准备run之CSS篇

时隔一年多又要准备面试嘞。唉,人生呐,真是变幻莫测哟~ 社招应该不会问很多css吧,,,但是应该也会问吧,,,应该是从好多好多问题里只抽一两个问问吧😭 哦还有h5&#xff…

zabbix简易入门:基本的网络监控、WEB监控、拓朴图规划

需求背景: 我们越来越发现:网络越来越复杂,网络、应用、云端……故障点随时可能发生,而我们不能人工盯着所有的问题,所以,网管软件是必须的。那么没有预算的情况下,我们只好自己布署简单的…

24届近5年浙江工业大学自动化考研院校分析

今天给大家带来的是浙江工业大学控制考研分析 满满干货~还不快快点赞收藏 一、浙江工业大学 学校简介 浙江工业大学(Zhejiang University of Technology),简称浙工大,主校区位于浙江省杭州市,是教育部与…

Stream API总结

Stream是Java 8提供的新特性,使得可以方便的对集合进行各种操作,本篇主要讲解StreamAPI常用方法。 Java8中有两大最为重要的改变。 第一个是 Lambda 表达式; 另外一个则是 Stream API(java.util.stream.*)。 Stream 是 Java8 中处理集合的关…

Java反射机制详解与使用方法大全!!!

❤ 作者主页:李奕赫揍小邰的博客 ❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~* 🍊 记得点赞、收藏、评论⭐️⭐️⭐️ 📣 认真学习!!!🎉🎉 文章目录 Java反射机制…

Node.js学习笔记-03

七、网络编程 1. 构建 TCP 服务 TCP 是面向连接的协议,显著特征 在传输之前需要3次握手形成会话。 客户端 ——请求连接——> 服务器端 ——响应——> 客户端 ——开始传输——> 服务器端。 2. 构建 UDP 服务 3. 构建 HTTP 服务 http模块 在node中HTT…

电脑数据怎么加密?电脑数据加密软件有哪些?

在生活和工作中,我们总离不开电脑,而电脑中那些重要的数据,需要我们加密保护。那么电脑数据该怎么加密呢?电脑数据加密软件又有哪些呢?下面我们就来了解一下吧。 电脑数据加密软件 一般来说,常见的电脑加密…