大家好,欢迎来到IT知识分享网。
目录
深拷贝和浅拷贝是对象复制的两种方式,它们在处理引用类型的字段时存在显著差异。下面将详细介绍它们的含义、区别,并提供代码示例。
1. 深拷贝(Deep Copy)
- 定义:深拷贝创建一个新对象,并且复制原对象中的所有字段,包括引用类型的字段。对于每个引用类型的字段,它都会创建一个新的实例,确保源对象和目标对象之间没有任何共享的引用。
- 递归地复制所有子对象。即使原始对象或拷贝对象修改其子对象,也不会互相影响。
- 特点:
- 基本数据类型的值会被复制。
- 引用数据类型的对象会被完全独立地复制。
2. 浅拷贝(Shallow Copy)
- 定义:浅拷贝创建一个新对象,该对象与原对象具有相同的值,但对引用类型字段只会复制引用地址,而不复制实际的对象。这意味着原对象和新对象的引用类型属性指向同一块内存。
- 不递归地复制对象所引用的子对象。它仅复制对象的基本数据类型和对引用类型的引用,因此原始对象和拷贝对象中对引用类型的修改会相互影响。
- 特点:
- 基本数据类型的值会被复制。
- 引用数据类型的对象会共享同一个实例。
3. 深拷贝和浅拷贝的区别
| 特性 | 浅拷贝 | 深拷贝 |
|---|---|---|
| 对基本类型 | 复制其值 | 复制其值 |
| 对引用类型 | 复制引用(共同使用同一对象) | 复制对象(各自独立的对象) |
| 影响 | 修改一个对象的引用类型字段会影响另一个对象 | 修改一个对象不会影响另一个对象 |
4. 示例代码
浅拷贝示例
class Address { String city; public Address(String city) { this.city = city; } } class Person implements Cloneable { String name; Address address; public Person(String name, Address address) { this.name = name; this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); // 浅拷贝 } } public class ShallowCopyExample { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address("New York"); Person person1 = new Person("Alice", address); Person person2 = (Person) person1.clone(); // 浅拷贝 System.out.println("Before modification:"); System.out.println("Person1 Address: " + person1.address.city); // 输出: New York System.out.println("Person2 Address: " + person2.address.city); // 输出: New York // 修改 person2 的地址 person2.address.city = "Los Angeles"; System.out.println("After modification:"); System.out.println("Person1 Address: " + person1.address.city); // 输出: Los Angeles (共享同一引用) System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles } }
深拷贝示例
class Address { String city; public Address(String city) { this.city = city; } // 深拷贝方法 public Address deepCopy() { return new Address(this.city); } } class Person { String name; Address address; public Person(String name, Address address) { this.name = name; this.address = address; } // 深拷贝方法 public Person deepCopy() { return new Person(this.name, this.address.deepCopy()); } } public class DeepCopyExample { public static void main(String[] args) { Address address = new Address("New York"); Person person1 = new Person("Alice", address); Person person2 = person1.deepCopy(); // 深拷贝 System.out.println("Before modification:"); System.out.println("Person1 Address: " + person1.address.city); // 输出: New York System.out.println("Person2 Address: " + person2.address.city); // 输出: New York // 修改 person2 的地址 person2.address.city = "Los Angeles"; System.out.println("After modification:"); System.out.println("Person1 Address: " + person1.address.city); // 输出: New York (不受影响) System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles } }
5.常用的方法
1.Java Object.clone() 方法
Object类提供的clone()方法可以用于实现浅拷贝。- 需要实现
Cloneable接口,并重写clone()方法。
2.序列化与反序列化
- 对象可以通过序列化为字节流,再反序列化为新对象。这种方式可以实现深拷贝。
- 需要实现
Serializable接口。
6.Spring Boot 中的常用方法
在 Spring Boot 中,通常使用以下方式来实现深拷贝:
使用 SerializationUtils
import org.springframework.util.SerializationUtils; byte[] bytes = SerializationUtils.serialize(originalObject); MyObject copiedObject = (MyObject) SerializationUtils.deserialize(bytes);
使用 ModelMapper 或 MapStruct
ModelMapper 和 MapStruct 都可以用来轻松地进行对象之间的映射,借此实现深拷贝。
7.Hutool 工具类
Hutool 提供了简单易用的工具类,可以进行深拷贝和浅拷贝:
浅拷贝
Person copy = ShallowUtil.clone(original);
深拷贝
Person deepCopy = CloneUtil.clone(original);
8.Guava 中的相关工具类
Guava 提供了 Immutable 集合来避免可变性,虽然不是直接的拷贝方法,但可以帮助管理不可变对象。
- ImmutableList
、ImmutableSet和ImmutableMap 用于创建不可变的集合,这样可以避免浅拷贝的问题。 - 不可变集合在创建后无法更改,这使得它们特别适合于多线程环境和函数式编程风格。
import com.google.common.collect.ImmutableList; public class ImmutableListExample { public static void main(String[] args) { // 创建一个不可变列表 ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Cherry"); System.out.println(immutableList); // 下面的操作会抛出 UnsupportedOperationException,因为该列表是不可变的 // immutableList.add("Date"); // Uncommenting this line will throw an exception } } import com.google.common.collect.ImmutableSet; public class ImmutableSetExample { public static void main(String[] args) { // 创建一个不可变集合 ImmutableSet<String> immutableSet = ImmutableSet.of("Red", "Green", "Blue"); System.out.println(immutableSet); // 下面的操作会抛出 UnsupportedOperationException,因为该集合是不可变的 // immutableSet.add("Yellow"); // Uncommenting this line will throw an exception } } import com.google.common.collect.ImmutableMap; public class ImmutableMapExample { public static void main(String[] args) { // 创建一个不可变映射 ImmutableMap<String, Integer> immutableMap = ImmutableMap.of( "Alice", 30, "Bob", 25, "Charlie", 35 ); System.out.println(immutableMap); // 下面的操作会抛出 UnsupportedOperationException,因为该映射是不可变的 // immutableMap.put("Dave", 40); // Uncommenting this line will throw an exception } }
总结
- 浅拷贝和深拷贝分别适用于不同的场景。
- 根据需要选择合适的拷贝方法,并利用现有的框架和库简化工作。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112163.html