Java对象克隆-浅拷贝与深拷贝

目录

1、对象的克隆

1.1 对象的浅拷贝

1.2 对象深拷贝


1、对象的克隆

1.1 对象的浅拷贝

在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。

要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。

public class Person implements Cloneable {

   private String name;

   private int age;

   public Person() {

   }

   public Person(String name, int age) {

      this.name = name;

      this.age = age;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

   public int getAge() {

      return age;

   }

   public void setAge(int age) {

      this.age = age;

   }

   protected Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      return obj;

   }

   public String toString() {

      return "Person [name=" + name + ", age=" + age + "]";

   }

}

注意: 该Person 类实现了Cloneable 重写了clone() 方法.

public static void main(String[] args) {

      Person p1 = new Person("jack", 28);

      System.out.println(p1);

      Person p2 = (Person) p1.clone();

      System.out.println(p2);

      // 不是同一个Person 对象.

      System.out.println(p1 == p2);

      // 修改p1 对象属性值,不影响 p2 对象的属性值.

      p1.setAge(30);

      System.out.println(p1);

      System.out.println(p2);

   }

Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

1.2 对象深拷贝

注意问题:

请看代码:

package cn.test.gz.myclone;

public class Person implements Cloneable {

   private String name;

   private int age;

   private Address add;

   public Person() {

   }

   public Person(String name, int age, Address add) {

      this.name = name;

      this.age = age;

      this.add = add;

   }

   public String getName() {

      return name;

   }

   public void setName(String name) {

      this.name = name;

   }

   public int getAge() {

      return age;

   }

   public void setAge(int age) {

      this.age = age;

   }

   public Address getAdd() {

      return add;

   }

   public void setAdd(Address add) {

      this.add = add;

   }

   protected Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      return obj;

   }

   @Override

   public String toString() {

      return "Person [name=" + name + ", age=" + age + ", add:" + add + "]";

   }

}

package cn.test.gz.myclone;

public class Address {

   private String country;

   private String city;

   public Address() {

   }

   public Address(String country, String city) {

      this.country = country;

      this.city = city;

   }

   public String getCountry() {

      return country;

   }

   public void setCountry(String country) {

      this.country = country;

   }

   public String getCity() {

      return city;

   }

   public void setCity(String city) {

      this.city = city;

   }

   public String toString() {

      return "country=" + country + ", city=" + city;

   }

}

注意:

Address add = new Address("中国", "广州");

      Person p1 = new Person("jack", 28, add);

      add.setCountry("美国");

      System.out.println(p1);

      Person p2 = (Person) p1.clone();

      System.out.println(p2);

      // 克隆的是两个不同的对象

      System.out.println(p1 == p2);

      // 但是对象内部的成员是同一个对象.

      System.out.println(p1.getAdd() == p2.getAdd());

解决办法:

package cn.test.gz.myclone;

public class Address implements Cloneable {

   private String country;

   private String city;

   public Address() {

   }

   public Address(String country, String city) {

      this.country = country;

      this.city = city;

   }

   public String getCountry() {

      return country;

   }

   public void setCountry(String country) {

      this.country = country;

   }

   public String getCity() {

      return city;

   }

   public void setCity(String city) {

      this.city = city;

   }

   public String toString() {

      return "country=" + country + ", city=" + city;

   }

   @Override

   public Object clone() {

      Object obj = null;

      try {

         obj = super.clone();

      } catch (CloneNotSupportedException e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

      }

      return obj;

   }

}

Person 类

protected Object clone() {

      Person p = null;

      try {

         p = (Person) super.clone();

      } catch (CloneNotSupportedException e) {

         e.printStackTrace();

      }

      p.add = (Address) add.clone();

      return p;

   }

当然也可以通过序列化机制来实现对象的克隆.

public static void main(String[] args) throws IOException, ClassNotFoundException {

      Address add = new Address("中国", "广州");

      Person p1 = new Person("jack", 28, add);

      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

            "c:\\person.txt"));

      oos.writeObject(p1);

      ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:\\person.txt"));

      Person p2=(Person)ois.readObject();

      System.out.println(p1==p2);

      System.out.println(p1.getAdd()==p2.getAdd());

   }

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

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

相关文章

论婚恋相亲交友软件的市场前景和开发方案H5小程序APP源码

随着移动互联网的快速发展和社交需求的日益增长,婚恋相亲交友软件小程序成为了越来越多单身人士的选择。本文将从市场前景、使用人群、盈利模式以及竞品分析等多个角度,综合论述这一领域的现状与发展趋势。 一、市场前景 在快节奏的现代生活中&#xf…

得物sign参数逆向分析与Python算法还原

文章目录 1. 写在前面2. 接口分析3. 断点分析4. Python算法还原 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚…

Postman调用OpenApi接口

首先你需要科学上网。。。。。 请求方式:post 请求地址:https://api.openai.com/v1/chat/completions 请求头: Authorization : Bearer key Content-Type : application/json Body : { "messages": [{ "role": &quo…

【论文精读】Bag of Tricks for Image Classification with Convolutional Neural Networks

这篇文章比较早了,2018年的 摘要 最近在图像分类研究方面取得的大部分进展可以归功于训练程序的改进,如数据增强和优化方法的改变。然而,在文献中,大多数改进要么作为实现细节简要提到,要么只在源代码中可见。在本文中…

CV method:最新Backbone---TransNeXt

文章目录 前言一、提出问题二、模型结构1. Pixel-focused Attention(像素聚焦注意力机制)2. Aggregating Diverse Attentions in a Single Mixer Query embedding3. ConvGLU4. 整体模型架构 三、方法论1. PFA设计原理2. Aggregating Diverse Attention原…

前端从零到一搭建脚手架并发布到npm

这里写自定义目录标题 一、为什么需要脚手架?二、前置-第三方工具的使用1. 创建demo并运行-4步新建文件夹 zyfcli,并初始化npm init -y配置入口文件 2.commander-命令行指令3. chalk-命令行美化工具4. inquirer-命令行交互工具5. figlet-艺术字6. ora-lo…

【算法】合并两个有序链表

本题来源---《合并两个有序链表》 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] /*** Definition for singl…

C++ - STL详解—vector类

一. vector的概念 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。 …

win/mac达芬奇19下载:DaVinci Resolve Studio 19

DaVinci Resolve Studio 19 是一款功能强大的视频编辑和调色软件,广泛应用于电影、电视和网络节目的后期制作。这款软件不仅提供了专业的剪辑、调色和音频处理工具,还引入了全新的DaVinci Neural Engine AI工具,对100多项功能进行了大规模升级…

Vue3(五):组件通信详解(九种方法)

主要有九种方法,以下是详细解释及使用方法: 1.props props实现父子间的通信,是使用频率最高的。 (1)父传子:属性值是非函数。 以Father.vue和Child.vue 为例。 父组件中,引入子组件并给子组…

34、链表-合并K个升序链表

思路 1、直接全部放入集合中,然后排序,在进行构造节点返回 2、使用归并排序的方式,两两排序合并,最后合并大的。 3、第三中思路就比较巧妙了,可以使用小根堆,每次弹出堆顶,最小值&#xff0c…

【计算机网络】http协议的原理与应用,https是如何保证安全传输的

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

基于 RT-Thread 的 CMUX 串口多路复用的详细使用

一、CMUX 软件包的介绍 CMUX(Connection Multiplexing ),即连接(串口)多路复用,其功能主要在一个真实的物理通道上虚拟多个通道,每个虚拟通道上的连接和数据通讯可独立进行。  CMUX 软件包常用…

DRF ModelSerializer序列化类

ModelSerializer序列化类 【0】准备 模型表创建 from django.db import modelsclass Book(models.Model):name models.CharField(max_length64, verbose_name书名)price models.DecimalField(max_digits6, decimal_places2, verbose_name价格)publish models.ForeignKey(…

【C++打怪之路】-- C++开篇

🌈 个人主页:白子寰 🔥 分类专栏:C打怪之路,python从入门到精通,魔法指针,进阶C,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~ &…

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,本地vue项目,详细解析区别(2024-04-19)

目录 1、区别(vue-cli2 与 vue-cli3 ) 2、例子1(vue2项目) 2.1 版本与命令行 2.2 项目本地截图 2.3 项目文件解析 (1)package.json 文件 (2)webpack.dev.conf.js文件 &#…

[大模型]Qwen-7B-hat Transformers 部署调用

Qwen-7B-hat Transformers 部署调用 环境准备 在autodl平台中租一个3090等24G显存的显卡机器,如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab,并且打开其中的终端开始环境配置、模型下…

NLP自然语言处理_序章

开一个新篇章,立一个flag,用一段时间来学习一下NLP,涨涨见识。 准备以B站 机器学习算法到transformer神经网络模型应用视频作为入门,此分类专门用于记录学习过程中的知识点以备自用。 一、何为NLP自然语言处理? NLP…

查看linux的主机配置脚本

废话不说 直接上指令 curl -Lso- bench.sh | bash 等待后,结果如图: 使用后没有问题,看情况使用 出事概不负责 介意勿用!!!

RabbitMQ 各种通信模式的Python实现

一、RabbitMQ 原理 1、基本原理 RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。支持多种客户端,如:Python、Java、Javascript、C#、C/C,Go等,支持AJ…