Java深度复制– Java复制对象
今天,我们将研究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类,克隆都可能意味着明显不同。