Java深度复制– Java复制对象

时间:2020-02-23 14:34:26  来源:igfitidea点击:

今天,我们将研究Java深层复制。
有时我们想获取一个Object的副本,但是Java只能在引用上工作,如果我们不想更改原始对象,则需要执行深度复制。
简单来说,对象的深层副本应与原始对象完全分离。

Java深度复制

获取对象深层副本的一种方法是使用序列化。
只是为了进行修改,Java中的序列化允许我们将对象转换为流,可以通过网络发送该流,也可以将其保存为文件或者存储在DB中以备后用。

让我们牢记这一点,并将其悬停在Java深层复制背后的基本思想上。

Java深层复制背后的基本思想是:

  • 有一个Java对象需要被(深度)克隆。

  • 第一步是将Model对象标记为Serializable,以便将该对象转换为Stream,以便可以将其写入文件/流ond并可以回读。

  • 读回对象后,我们将获得原始对象的深层克隆。

  • 请注意,当要深度复制的类可序列化并且其所有变量也可序列化时,此方法可以正常工作。
    否则它将无法正常工作,并且您会得到java.io.NotSerializableException

  • 如果这些类不可序列化,则唯一的选择是编写一个自定义方法,以逐个字段复制对象变量以获取深层副本。

如何进行深度复制?

现在就是概述对象深层复制的过程。
让我们看看它是如何以编程方式完成的:

/**
 * Makes a deep copy of any Java object that is passed.
 */
 private static Object deepCopy(Object object) {
 try {
   ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
   ObjectOutputStream outputStrm = new ObjectOutputStream(outputStream);
   outputStrm.writeObject(object);
   ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
   ObjectInputStream objInputStream = new ObjectInputStream(inputStream);
   return objInputStream.readObject();
 }
 catch (Exception e) {
   e.printStackTrace();
   return null;
 }
 }

上面的方法接受一个Object并返回其深层副本。

此方法是即用型方法。
可以称为:

//Student should be Serializable, primitive and Strings are Serilizable too.
Student john = new Student("John", 13, "23, 23rd Street, Goa");
Student abraham = (Student) deepCopy(john);

深拷贝与浅拷贝

如我们所见,深层复制是一个非常简单的概念,但仍然与诸如对象的浅层复制之类的术语混淆。

重要的是要了解,浅表副本只是对同一对象的另一个引用。
让我们看一下代码如何为对象创建浅表副本:

List firstList, secondList;
firstList = new ArrayList();
firstList.add("Hello:);

secondList = firstList;
secondList.add("World");

在上面的示例中,语句" secondList = firstList;"对firstList进行了浅表复制。
当第二个元素添加到secondList时,这也意味着firstList也包含两个元素,因为两个列表实际上是相同的。

对象clone()方法

通常认为对象clone()方法可生成目标对象的副本。

这是javadoc所说的:

请注意,这表明克隆的一侧可能是目标对象,而另一侧的克隆甚至可能不等于实际对象。
并假设是否甚至支持克隆。

总而言之,对于每个Java类,克隆都可能意味着明显不同。