ITPub博客

首页 > 数据库 > 数据库开发技术 > JAVA 基础知识:浅拷贝和深拷贝

JAVA 基础知识:浅拷贝和深拷贝

原创 数据库开发技术 作者:灸哥漫谈 时间:2023-12-13 00:32:30 0 删除 编辑

在 JAVA 编程中,对象的复制是一种基本操作。然而,不同类型的对象复制可能导致不同的结果。

一、什么是浅拷贝?

浅拷贝是指在复制对象时,只复制对象本身和其非引用类型的成员变量,而不复制引用类型的成员变量。

这意味着新对象和原对象的引用类型成员变量仍然指向相同的对象。

在Java中,常见的浅拷贝方式包括对象的 clone() 方法和一些库中提供的工具类,如 ObjectUtils.clone()。

public class Person implements Cloneable {    private String name;    private Address address;
public Person(String name, Address address) { this.name = name; this.address = address; }
// Getters and setters...
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}
public class Address { private String city; private String zipCode;
// Getters and setters...}
// 在使用中Address originalAddress = new Address("City", "12345");Person originalPerson = new Person("John", originalAddress);
try { // 浅拷贝 Person clonedPerson = (Person) originalPerson.clone();
// 修改原对象的引用类型成员变量 originalAddress.setCity("New City");
// 输出新对象的引用类型成员变量 System.out.println(clonedPerson.getAddress().getCity()); // 输出 "New City"} catch (CloneNotSupportedException e) { e.printStackTrace();}

在上述示例中,originalPerson 和 clonedPerson 共享同一个 Address 对象,因此对 originalAddress 的修改也会影响到 clonedPerson。

二、什么是深拷贝?

深拷贝是指在复制对象时,不仅复制对象本身和其非引用类型的成员变量,还对引用类型的成员变量进行递归复制,生成新的对象。

这样,新对象和原对象的引用类型成员变量将分别指向不同的对象。

在Java中,实现深拷贝的方式主要有手动编写深拷贝方法、使用序列化和反序列化,以及一些第三方库的支持。

import java.io.*;
public class DeepCloneUtil { @SuppressWarnings("unchecked") public static <T extends Serializable> T deepClone(T obj) { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos)) { // 将对象写入字节数组输出流 oos.writeObject(obj); oos.flush();
// 从字节数组输出流读取对象 try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()))) { return (T) ois.readObject(); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } }}
// 在使用中Address originalAddress = new Address("City", "12345");Person originalPerson = new Person("John", originalAddress);
// 深拷贝Person clonedPerson = DeepCloneUtil.deepClone(originalPerson);
// 修改原对象的引用类型成员变量originalAddress.setCity("New City");
// 输出新对象的引用类型成员变量System.out.println(clonedPerson.getAddress().getCity()); // 输出 "City"

在上述示例中,clonedPerson 的 Address 对象与 originalPerson 的 Address 对象是独立的,修改 originalAddress 不会影响到 clonedPerson。

3、如何选择浅拷贝和深拷贝?

选择浅拷贝还是深拷贝取决于具体的业务需求和对象结构。在一些场景中,浅拷贝已经足够满足要求,而在另一些场景中,需要确保复制对象的所有成员变量都是独立的,这时候深拷贝更为合适。

浅拷贝的应用场景

  • 对象内部的引用类型成员变量本身就不需要被复制,或者共享同一个实例对程序逻辑无影响。

  • 复制对象的目的主要是为了创建一个对象的副本,但不关心其内部引用类型成员变量的变化。

深拷贝的应用场景

  • 需要确保复制对象的所有成员变量都是独立的,修改其中一个对象的成员变量不会影响到其他对象。

  • 复制对象的目的主要是为了创建一个完全独立的副本,任何对副本的修改都不应该影响到原对象。


在Java中,深入理解浅拷贝和深拷贝是编写高质量、高性能代码的关键。

通过灵活选择适当的拷贝方式,可以确保对象在复制过程中得到正确的处理,同时避免引起潜在的bug。

在实际项目中,根据具体需求和场景选择适当的拷贝方式,将有助于提高代码的可维护性和性能。

原文作者:灸哥漫谈;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-11-26

  • 博文量
    368
  • 访问量
    173281