目的地-Destination 前程似锦、未来可期、寻得良人、共赴白头,祝你也祝我。
博主 目的地-Destination
沪ICP备16003146号-2沪公网安备 31010702004922号萌ICP备20238488号博主 昨天 17:25 在线自豪地使用 Typecho 建站搭配使用 🌻Sunny 主题当前在线 28 人
歌曲封面 未知作品

沪ICP备16003146号-2

沪公网安备 31010702004922号

萌ICP备20238488号

网站已运行 7 年 342 天 1 小时 7 分

Powered by Typecho & Sunny

29 online · 49 ms

Title

在java中,什么情况下要使用深拷贝?为什么要使用深拷贝?怎么使用深拷贝?

Chrison

·

烂笔头

·

Article

在Java中,深拷贝(Deep Copy)通常用于以下情况:

1. 当对象包含引用类型成员时

如果一个对象包含对其他对象的引用,那么在进行浅拷贝时,这些引用也会被拷贝,导致原始对象和拷贝对象共享相同的引用类型成员。这意味着对其中一个对象的引用类型成员所做的任何更改都会影响到另一个对象。为了避免这种情况,就需要使用深拷贝。

2. 当对象不可变时

当对象需要保持不可变性时,深拷贝可以确保对象的状态不会被外部修改。例如,如果你有一个不可变的类,你需要确保一旦对象创建后,它的状态就不能被改变。这时,如果你需要创建一个新的对象,你应该使用深拷贝来确保新对象是独立的。

3. 当对象需要被序列化时

在进行对象序列化时,如果对象中包含其他对象的引用,那么这些引用也需要被正确地序列化。在序列化过程中,通常会使用深拷贝来确保所有的对象都被正确地序列化,而不是只拷贝引用。

4. 当对象需要被克隆时

当你需要克隆一个对象,并且该对象包含其他对象的引用时,使用深拷贝可以确保每个对象都是独立的。这对于避免并发问题和保证数据一致性非常重要。

5. 当对象用于多线程环境时

在多线程环境中,共享的对象可能会导致竞态条件和数据不一致的问题。使用深拷贝可以确保每个线程都有对象的一个独立副本,从而避免这些问题。

为什么要使用深拷贝?

  1. 保证对象独立性:深拷贝可以确保拷贝后的对象与原始对象之间没有引用关联,从而保证它们是完全独立的。
  2. 维护不变性:对于不可变对象来说,深拷贝可以帮助保持对象的状态不变。
  3. 简化并发编程:在多线程环境中,使用深拷贝可以减少锁的使用,提高程序性能。
  4. 避免副作用:深拷贝可以防止对一个对象的操作无意中影响到另一个对象,从而避免副作用。
  5. 简化数据处理:在数据处理过程中,深拷贝可以使数据结构的修改变得简单,避免了复杂的数据同步逻辑。

如何实现深拷贝?

  1. 实现Serializable接口并通过序列化/反序列化:这是一种常见的实现方式,适用于对象中的所有成员都是可序列化的。
  2. 使用org.apache.commons.lang3.SerializationUtils:Apache Commons Lang库提供了一个方便的工具类SerializationUtils,可以轻松实现对象的深拷贝。
  3. 手动实现深拷贝:对于复杂的对象,你可能需要手动实现深拷贝逻辑,这通常涉及递归地复制对象的所有成员,包括嵌套的引用类型。
  4. 使用特定库提供的深拷贝工具:例如,Google Guava库提供了一些工具方法来帮助实现深拷贝,特别是针对集合类。

总之,深拷贝在Java中是非常有用的,尤其是在处理包含引用类型成员的对象时,它可以确保对象的独立性和不变性,从而提高程序的稳定性和性能。

示例代码

♾️ html 代码:
    import java.io.*;

/**
 * 深拷贝
 */
public class DeepCopyUtil implements Serializable {


    public static <T extends Serializable> T deepCopy(T object) {

        try {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            ObjectOutputStream oos = new ObjectOutputStream(baos);

            oos.writeObject(object);


            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

            ObjectInputStream ois = new ObjectInputStream(bais);

            return (T) ois.readObject();

        } catch (IOException | ClassNotFoundException e) {

            throw new RuntimeException(e);

        }

    }

}

调用方法

♾️ html 代码:
public static void main(String[] args) {
    WpOrder oldOrder.........;
    WpOrder newOrder = DeepCopyUtil.deepCopy(oldOrder);
}
现在已有 1042 次阅读,10 条评论,3 人点赞
湘铭呀!
Comment:共10条
发表
  1. 头像
    @

    好友

    团团
    果然隔行如隔山,表示看不懂😭
    · Chrome · 中国广东省深圳市电信

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      哈哈哈,那没事。这不重要。
      · 火狐浏览器 · 中国江苏省无锡市江阴市电信

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
  2. 头像
    @
    感谢分享,谢谢
    · Chrome · 中国上海市移动

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      😀
      · 火狐浏览器 · 中国江苏省无锡市电信

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
  3. 头像
    @

    好友

    柳橙睿
    你换主题了?🙃
    · Chrome · 中国湖北省武汉市电信

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      是的啊 ,哈哈哈。
      · 火狐浏览器 · 中国江苏省无锡市电信

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
  4. 头像
    @
    很好奇那浅拷贝一般会用在什么场景呢?
    · Chrome · 中国湖南省长沙市联通

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      浅拷贝,只会复制基本数据类型,int,double等,而其他对象类型均是同地址引用(一个修改所引用的均会被修改)。如果在后面的使用过程中,你并不会修改变其更对象类型,那就浅拷贝就可以了。浅拷贝也可以避免不必要的内存消耗和对象复制。
      · 火狐浏览器 · 中国江苏省无锡市电信IDC机房

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
  5. 头像
    @

    好友

    Teacher Du
    不懂,但不影响我来评论~
    · Chrome · 中国北京市联通

    👍

    💖

    💯

    💦

    😄

    🪙

    👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
    1. 头像
      @
      哈哈哈。可以可以😀
      · 火狐浏览器 · 中国江苏省无锡市电信

      👍

      💖

      💯

      💦

      😄

      🪙

      👍 0 💖 0 💯 0 💦 0 😄 0 🪙 0
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主