当前位置: 首页 > news >正文

网站开发公司 经营范围eclipse做网站表格

网站开发公司 经营范围,eclipse做网站表格,进入百度知道首页,泉州网站建设泉州字符串和对象的深拷贝和浅拷贝【一】基本介绍【1】浅拷贝【2】深拷贝【二】字符串的拷贝【1】字符串的 “浅拷贝”【2】字符串的 “深拷贝”【三】对象的拷贝【1】浅拷贝(Shallow Copy)【2】深拷贝(Deep Copy)【四】字符串和对象拷…

字符串和对象的深拷贝和浅拷贝

  • 【一】基本介绍
    • 【1】浅拷贝
    • 【2】深拷贝
  • 【二】字符串的拷贝
    • 【1】字符串的 “浅拷贝”
    • 【2】字符串的 “深拷贝”
  • 【三】对象的拷贝
    • 【1】浅拷贝(Shallow Copy)
    • 【2】深拷贝(Deep Copy)
  • 【四】字符串和对象拷贝的核心区别
  • 【五】介绍ObjectUtil的clone方法
    • 【1】ObjectUtil.clone的核心功能
    • 【2】使用案例
      • (1)基本类型与字符串拷贝
      • (2)数组拷贝(深拷贝)
      • (3)自定义对象拷贝
    • 【3】实现原理(Hutool为例)

【一】基本介绍

【1】浅拷贝

仅拷贝数据的 “表层”。对于基本数据类型(如int、float),直接拷贝值;对于引用类型(如对象、数组),仅拷贝引用地址(原对象和拷贝对象共享同一个引用对象)。

【2】深拷贝

拷贝数据的 “全部层级”。不仅拷贝基本类型的值,还会递归拷贝所有引用类型所指向的对象,原对象和拷贝对象完全独立,互不影响。

【二】字符串的拷贝

字符串(String)是特殊的引用类型,其拷贝行为受不可变性影响(String类被final修饰,一旦创建不可修改)。

【1】字符串的 “浅拷贝”

本质是引用传递,由于字符串不可变,直接赋值或使用clone()(字符串的clone()方法返回自身)时,拷贝的是引用,但因不可变性,不会出现共享修改的问题。

String original = "hello";
String copy = original; // 拷贝引用(浅拷贝)// 字符串不可变:修改copy会创建新对象,不影响original
copy = "world"; 
System.out.println(original); // 输出:hello(原对象未变)

特点:原字符串和拷贝字符串的引用指向同一对象,但因不可修改,看似 “安全”,实际仍是浅拷贝(共享引用)。

【2】字符串的 “深拷贝”

无需额外操作
由于字符串不可变,任何 “修改” 都会创建新对象,因此即使是浅拷贝,也能达到类似深拷贝的效果。若需显式创建新字符串对象,可通过以下方式:

String original = "hello";
// 方式1:使用构造方法创建新对象(深拷贝效果)
String deepCopy1 = new String(original); 
// 方式2:使用intern()(但可能复用常量池对象,视情况而定)
String deepCopy2 = original.intern(); // 修改拷贝对象不会影响原对象(因不可变,实际是创建新对象)
deepCopy1 = deepCopy1 + "world"; 
System.out.println(original); // 输出:hello(原对象未变)

特点:字符串的不可变性使得 “浅拷贝” 和 “深拷贝” 的区别被弱化 —— 无论哪种方式,修改拷贝都不会影响原对象,因此通常无需专门实现深拷贝。

【三】对象的拷贝

对象(如自定义类实例)是典型的引用类型,其拷贝需明确区分浅拷贝和深拷贝,否则可能因共享引用导致意外问题。

【1】浅拷贝(Shallow Copy)

仅拷贝对象本身和基本类型字段,引用类型字段仅拷贝引用(原对象和拷贝对象共享引用对象)。

(1)实现方式:
重写Object类的clone()方法(需实现Cloneable接口)。
默认的clone()方法为浅拷贝。

(2)示例

class Address { // 引用类型(地址类)String city;public Address(String city) { this.city = city; }
}class Person implements Cloneable { // 实现Cloneable接口String name; // 基本类型(String是特殊引用类型,但不可变)int age; // 基本类型Address address; // 引用类型public Person(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}// 重写clone()实现浅拷贝@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 默认浅拷贝}
}// 测试浅拷贝
public class ShallowCopyDemo {public static void main(String[] args) throws CloneNotSupportedException {Address addr = new Address("Beijing");Person original = new Person("Alice", 20, addr);// 浅拷贝Person copy = (Person) original.clone();// 1. 基本类型和不可变引用类型(String):修改拷贝不影响原对象copy.name = "Bob";copy.age = 21;System.out.println(original.name); // 输出:Alice(原对象name未变)System.out.println(original.age);  // 输出:20(原对象age未变)// 2. 引用类型(Address):修改拷贝的引用对象,原对象受影响copy.address.city = "Shanghai";System.out.println(original.address.city); // 输出:Shanghai(原对象address被修改)}
}

结论:浅拷贝中,引用类型字段(如Address)的修改会同时影响原对象和拷贝对象(因共享引用)。

【2】深拷贝(Deep Copy)

完全拷贝对象及其所有引用类型字段指向的对象,原对象和拷贝对象完全独立。

(1)实现方式:
方式 1:重写clone()方法时,对引用类型字段也进行clone()(递归浅拷贝)。
方式 2:通过序列化(Serializable)将对象转为字节流,再反序列化为新对象。
方式 3:使用 JSON 工具(如 Jackson、Gson)将对象转为 JSON 字符串,再解析为新对象。

(2)示例一:递归 clone 实现深拷贝

class Address implements Cloneable { // 引用类型实现CloneableString city;public Address(String city) { this.city = city; }@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // Address的浅拷贝}
}class Person implements Cloneable {String name;int age;Address address;public Person(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}// 重写clone()实现深拷贝:对引用类型字段也进行clone@Overrideprotected Object clone() throws CloneNotSupportedException {Person copy = (Person) super.clone(); // 先浅拷贝Person本身copy.address = (Address) this.address.clone(); // 再拷贝引用类型Addressreturn copy;}
}// 测试深拷贝
public class DeepCopyDemo {public static void main(String[] args) throws CloneNotSupportedException {Address addr = new Address("Beijing");Person original = new Person("Alice", 20, addr);// 深拷贝Person copy = (Person) original.clone();// 修改拷贝的引用类型字段copy.address.city = "Shanghai";System.out.println(original.address.city); // 输出:Beijing(原对象不受影响)}
}

(3)示例二:序列化实现深拷贝

import java.io.*;class Address implements Serializable { // 需实现SerializableString city;public Address(String city) { this.city = city; }
}class Person implements Serializable { // 需实现SerializableString name;int age;Address address;// 深拷贝方法:序列化+反序列化public Person deepCopy() throws IOException, ClassNotFoundException {// 序列化ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);// 反序列化ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (Person) ois.readObject();}
}// 测试
public class SerializationDemo {public static void main(String[] args) throws Exception {Person original = new Person("Alice", 20, new Address("Beijing"));Person copy = original.deepCopy();copy.address.city = "Shanghai";System.out.println(original.address.city); // 输出:Beijing(完全独立)}
}

结论:深拷贝中,原对象和拷贝对象的所有字段(包括引用类型)完全独立,修改互不影响。

【四】字符串和对象拷贝的核心区别

(1)字符串(String)
拷贝引用,因不可变性,修改时会创建新对象,原对象不受影响。与浅拷贝效果一致(因不可变性,无需递归拷贝) 不可变性导致 “浅拷贝即安全”,无需专门深拷贝

(2)对象(引用类型)
引用类型字段共享引用,修改会相互影响。完全拷贝所有层级,修改互不影响 需显式实现深拷贝(如递归clone、序列化)

(3)适用场景
1-浅拷贝:适用于对象中仅包含基本类型或不可变引用类型(如String),或需共享引用对象的场景(如多对象共享配置信息)。
2-深拷贝:适用于对象包含可变引用类型(如自定义类、数组),且需完全隔离原对象和拷贝对象的场景(如多线程操作、数据备份)。

【五】介绍ObjectUtil的clone方法

在 Java 工具类中,ObjectUtil通常是一个自定义或第三方工具类(如 Hutool、Apache Commons 等),用于简化对象操作,其中clone方法用于实现对象的拷贝。不同工具类的clone方法实现可能略有差异,但核心功能都是封装对象克隆的复杂逻辑,提供更简洁的 API。以下以Hutool 工具类库的ObjectUtil.clone方法为例,详细介绍其功能、用法和特性

【1】ObjectUtil.clone的核心功能

ObjectUtil.clone方法的主要作用是快速实现对象的深拷贝或浅拷贝,无需手动处理Cloneable接口、序列化等底层细节,简化对象拷贝的代码实现。
Hutool 的ObjectUtil中,clone方法通过判断对象类型,自动选择最优的拷贝方式:

(1)对于基本类型、字符串(String)等不可变类型,直接返回原值(因不可变特性,无需拷贝)。
(2)对于数组,递归拷贝数组元素(深拷贝)。
(3)对于实现Cloneable接口的对象,调用其clone()方法(可能是浅拷贝,取决于对象自身实现)。
(4)对于实现Serializable接口的对象,通过序列化 + 反序列化实现深拷贝。
(5)对于普通对象,尝试通过反射拷贝字段(深拷贝)。

【2】使用案例

(1)基本类型与字符串拷贝

import cn.hutool.core.util.ObjectUtil;public class CloneDemo {public static void main(String[] args) {// 字符串拷贝(因不可变,直接返回引用,但不影响安全性)String str = "hello";String strClone = ObjectUtil.clone(str);System.out.println(str == strClone); // true(共享引用,因不可变安全)// 基本类型包装类拷贝Integer num = 123;Integer numClone = ObjectUtil.clone(num);System.out.println(num == numClone); // true(Integer常量池复用)}
}

(2)数组拷贝(深拷贝)

import cn.hutool.core.util.ObjectUtil;public class ArrayCloneDemo {public static void main(String[] args) {int[] arr = {1, 2, 3};int[] arrClone = ObjectUtil.clone(arr);arrClone[0] = 100;System.out.println(arr[0]); // 1(原数组不受影响,深拷贝)}
}

(3)自定义对象拷贝

假设存在自定义类User(实现Serializable接口以支持深拷贝)

import java.io.Serializable;class User implements Serializable {private String name;private int age;private Address address; // 引用类型字段// 构造方法、getter、setter省略
}class Address implements Serializable {private String city;// 构造方法、getter、setter省略
}

使用ObjectUtil.clone实现深拷贝:

import cn.hutool.core.util.ObjectUtil;public class ObjectCloneDemo {public static void main(String[] args) {Address addr = new Address("Beijing");User user = new User("Alice", 20, addr);// 深拷贝User userClone = ObjectUtil.clone(user);// 修改拷贝对象的引用字段userClone.getAddress().setCity("Shanghai");// 原对象不受影响(深拷贝成功)System.out.println(user.getAddress().getCity()); // Beijing}
}

【3】实现原理(Hutool为例)

ObjectUtil.clone的底层逻辑大致分为以下步骤:
(1)判断对象类型:
若为null,直接返回null。
若为基本类型或字符串,返回原值(利用不可变性)。
若为数组,递归拷贝每个元素(数组的深拷贝)。

(2)尝试克隆方式:
若对象实现Cloneable接口,调用其clone()方法(注意:若对象自身clone()是浅拷贝,结果仍为浅拷贝)。
若对象实现Serializable接口,通过序列化(ObjectOutputStream)和反序列化(ObjectInputStream)生成新对象(深拷贝)。
若以上均不满足,通过反射拷贝对象的所有字段(包括私有字段),递归处理引用类型字段(深拷贝)。

http://www.dtcms.com/a/606628.html

相关文章:

  • 建立网站 域名 服务器7一12岁手工简单又实用
  • kotlin 集成 unity
  • 麻辣烫配方教授网站怎么做前端做的好的网站
  • [Unity Shader Base] RayMarching in Cloud Rendering
  • Java后端常用技术选型 |(六)避坑手册
  • 教育网站平台建设对网站做维护
  • RUST实现简易随机密码生成器
  • 个人主页网站网站正在建设中源码
  • 网站邮箱配置百度seo哪家公司好
  • wordpress建站 购物网页设计实训报告不足
  • 蚂蚁与浙大签约,共建大数据认知计算联合研究中心
  • Ingress、Kubernetes数据存储相关概念及相关实验案例
  • 深圳做棋牌网站建设哪家好衡水专业网站制作
  • 建设项目环境影响评价登记表网站医院网站建设方案详细
  • 虚幻引擎 5.7 现已发布
  • 构建高效的多模态AI数据平台:从海量数据到智能进化的完整指南
  • 传奇发布网站排行网站建设哪方面最重要的呢
  • 消息队列终极选型:RabbitMQ、RocketMQ、Kafka与ActiveMQ深度对比
  • 超市网站建设费用泉港网站建设推广服务公司
  • 【OpenCV + VS】图像缩放与插值
  • 拖拽式建站平台国外网站做acm题目比较好
  • Vue——vue2中的mixin有哪些问题
  • 用 Rust 打造可复现的 ASCII 艺术渲染器:从像素到字符的完整工程实践
  • 台州企业自助建站代理app软件
  • 31.网络云服务
  • 网站开发与软件开发的区别重庆企业网站开发方案
  • 深圳公司网站建设公司郑州排名前十的科技公司
  • 做画册好的网站企业查询app
  • 算法学习笔记-贪心算法总结2
  • 网站开发技术方案龙岩资讯