关于浅克隆和深克隆入门理解

news2024/11/22 6:38:51

浅克隆:需要类实现Cloneable,并重写clone()方法

一般在重写clone()方法时,将返回值类型强转为自己类,避免每次克隆之后需要强转

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        A a1=new A();
        A a2 = a1.clone();

        //克隆之后 a1和a2是两个不同对象  内容相同
        System.out.println(a1==a2);//false
        System.out.println(a1);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println("--------------------------------------");

        //浅克隆之后,对String类型和8种基本类型(包装类)的改变不会影响另外一个对象的属性内容
        a1.setA(5);
        a1.setB(6);
        a1.setC("7");
        a1.setE("8");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='1'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
        System.out.println("--------------------------------------");

        //但是浅克隆对自定义类型的成员变量的改变,会影响另外一个对象 说明自定义对象在a1和a2中的引用地址指向了同一个对象
        a1.getD().setName("改了");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='改了'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='改了'}, e='4'}
        a2.getD().setName("又改了");
        System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='又改了'}, e='8'}
        System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='又改了'}, e='4'}

    }

}
class A implements Cloneable{
    int a=1;
    Integer b=2;
    String c=new String("3");
    D d=new D();
    String e="4";

    @Override
    public String toString() {
        return "A{" +
                "a=" + a +
                ", b=" + b +
                ", c='" + c + '\'' +
                ", d=" + d +
                ", e='" + e + '\'' +
                '}';
    }

    public D getD() {
        return d;
    }

    public void setD(D d) {
        this.d = d;
    }

    public String getE() {
        return e;
    }

    public void setE(String e) {
        this.e = e;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public Integer getB() {
        return b;
    }

    public void setB(Integer b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    @Override
    protected A clone() throws CloneNotSupportedException {
        return (A)super.clone();
    }
}
class D{
    String name="1";

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "D{" +
                "name='" + name + '\'' +
                '}';
    }
}

画张图表示

下面是深克隆的一种写法

让自定义类也实现克隆,并重写clone方法

然后在对象类的克隆方法改写成下面

这样再运行上面代码,  D就是不同的对象了,克隆之后,无论谁改变d的属性,都只影响自己

以集成工具默认重写equals和hashcode不影响执行结果

深克隆还有其他写法

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

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

相关文章

【搭建私人图床】本地PHP搭建简单Imagewheel云图床,在外远程访问

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…

Linux——(第十章)进程管理

目录 一、概述 二、常用指令 1.ps查看当前系统进程状态 2.kill 终止进程 3.pstree 查看进程树 4.top 实时监控系统进程状态 5.netstat 监控网络状态 一、概述 (1)进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体&#…

Redis 常用命令

目录 全局命令 1)keys 2)exists 3) del(delete) 4)expire 5)type SET命令 GET命令 MSET 和 MGET命令 其他SET命令 计数命令 redis-cli,进入redis 最核心的命令:我们这里只是先介绍 set 和 get 最简单的操作…

IP地址,子网掩码,默认网关,DNS讲解

IP地址:用来标识网络中一个个主机,IP有唯一性,即每台机器的IP在全世界是唯一的。 子网掩码:用来判断任意两台计算机的ip地址是否属于同一子网络的根据。最为简单的理解就是两台计算机各自的ip地址与子网掩码进行and运算后&#x…

常用排序算法

一、插入排序1、直接插入排序2、折半插入排序3、希尔排序 二、交换排序1、冒泡排序2、快速排序 三、选择排序1、简单选择排序2、堆排序(1)调整堆(2)创建堆 四、归并排序五、基数排序六、各种排序方法的比较 将一组杂乱无章的数据按…

Zookeeper应用场景和底层设计

一、什么是zookeeper Zookeeper是一个开源的分布式协调服务框架,它是服务于其它集群式框架的框架。 【简言之】 有一个服务A,以集群的方式提供服务。只需要A专注于它提供的服务就可以,至于它如何以多台服务器协同完成任务的事情&#xff0c…

9.14号作业

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 有些功能&#xff0c;不会 #include <iostream>using namespace std; //创建vector类 class Vector { private:int *data;int size;int capacity; public://无参构造Vector(){}//拷贝构造Vector(c…

2023年最新 Nonobot2 制作QQ聊天机器人详细教程(每周更新中)

协议端 go-cqhttp 安装 使用 mirai 以及 MiraiGo 开发的 cqhttp golang 原生实现&#xff0c;并在 cqhttp 原版 的基础上做了部分修改和拓展。 测试版下载地址&#xff1a;https://github.com/Mrs4s/go-cqhttp/releases 正式版下载地址&#xff1a;https://github.com/Mrs4s…

广义表基础知识

广义表 (又称列表 Lists)是 n > 0个元素 . a0,a1....an-1的有限序列&#xff0c;其中每一个 ai 或者是原子&#xff0c;或者是一个广义表 广义表通常记作: LS (a1&#xff0c;a2&#xff0c;.....&#xff0c;an&#xff09;&#xff0c; LS为表名&#xff0c;n为表的长度&…

使用 LoRA 和 QLoRA 对大型语言模型进行参数高效的微调

概述 随着我们深入研究参数高效微调 (PEFT) 的世界,了解这种变革性方法背后的驱动力和方法变得至关重要。在本文中,我们将探讨 PEFT 方法如何优化大型语言模型 (LLM) 对特定任务的适应。我们将揭开 PEFT 的优点和缺点,深入研究 PEFT 技术的复杂类别,并破译两种卓越技术的内…

SpingMyc项目如何搭建

目录 一、创建项目 二、环境搭建 &#xff08;1&#xff09;引入相关依赖 &#xff08;2&#xff09;在web.xml中配置前端控制器DispatcherServlet &#xff08;3&#xff09;编写SpringMVC核心配置文件springmvc.xml 三、测试是否成功 &#xff08;1&#xff09;编写控…

Java反射机制简单入门

标题 反射能干嘛获取Class对象的三种方式下面开始重点&#xff0c;需要掌握获取类的构造器并进行操作获取成员变量获取成员方法 这块建议先听第一个视频入门&#xff0c;第二个视频深入了解 视频学习地址1 视频学习地址1 正射:知道某个类&#xff0c;类的地址&#xff0c;通过…

在Linux和Windows上安装分布式事务seata

1 前言 官网地址&#xff1a;https://seata.io/ 源码地址&#xff1a;https://github.com/seata/seata 官网手册&#xff1a;https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html Seata&#xff0c;一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简…

软件设计模式系列之五——建造者模式

1 模式的定义 建造者模式是一种对象创建型设计模式&#xff0c;它将一个复杂对象的构建过程与其表示分离。这意味着你可以使用相同的构建过程来创建不同类型的对象&#xff0c;而不必关心每个对象的内部细节。这种模式适用于构建具有复杂配置的对象&#xff0c;例如具有多个可…

查看selenium具体版本的方法

1、 查看自己selenium版本 方法一&#xff1a; 本机进入CMD 在cmd窗口中输入 pip show selenium如果是在Pycharm中直接安装的selenium。则有可能会有如下提示。那么请尝试方法二。 方法二&#xff1a; 在pycharm中查看selenium版本 步骤一&#xff1a;在pycharm里打开命…

SpringMVC系列(五)之JSR303和拦截器

目录 一. JSR303 1.1 JSR303是什么 1.2 为什么要使用JSR303 1.3 JSR303常用注解 1.4 JSR303快速入门 1. 导入相关pom依赖 2. 配置校验规则 3. 入门示例 二. SpringMVC的拦截器 2.1 什么是拦截器 2.2 拦截器与过滤器的区别 2.3 拦截器工作原理 2.4 入门示例 1. 创建…

Gin路由中间件详解

什么是中间件 Gin 中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函 数, 最后一个 func 回调函数前面触发的方法 都可以称为中间件。 中间件操作演示 方法一: 直接写在func,回调函数内 r.GET("/middle",func(ctx *gin.Cont…

Pytorch中张量矩阵乘法函数(mm, bmm, matmul)使用说明,含高维张量实例及运行结果

Pytorch中张量矩阵乘法函数使用说明 1 torch.mm() 函数1.1 torch.mm() 函数定义及参数1.2 torch.bmm() 官方示例 2 torch.bmm() 函数2.1 torch.bmm() 函数定义及参数2.2 torch.bmm() 官方示例 3 torch.matmul() 函数3.1 torch.matmul() 函数定义及参数3.2 torch.matmul() 规则约…

黑马头条 热点文章实时计算、kafkaStream

热点文章-实时计算 1 今日内容 1.1 定时计算与实时计算 1.2 今日内容 kafkaStream 什么是流式计算kafkaStream概述kafkaStream入门案例Springboot集成kafkaStream 实时计算 用户行为发送消息kafkaStream聚合处理消息更新文章行为数量替换热点文章数据 2 实时流式计算 2…

【C++】哈希思想的应用——位图、布隆过滤器和哈希切割

前言&#xff1a; 前面我们学习了unordered_map和unordered_set和哈希表哈希桶等&#xff0c;并且我们自己用哈希桶封装了unordered_map和unordered_set。我们知道哈希的查找效率非常高为O(1)&#xff0c;本章我们将延续哈希的思想&#xff0c;共同学习哈希的应用。 目录 &am…