java 对象深度复制
Today we will look into Java deep copy. Sometimes we want to get a copy of an Object, but java works on reference and if we don’t want to alter the original object then we need to perform deep copy. In simple terms, deep copy of an Object should be completely detached from the original object.
今天,我们将研究Java深层复制。 有时我们想获取一个Object的副本,但是Java在引用上起作用,如果我们不想更改原始对象,则需要执行深度复制。 简单来说,对象的深层副本应与原始对象完全分离。
Java深度复制 (Java Deep Copy)
One of the way to get a deep copy of an Object is using Serialization. Just to revise, Serialization in Java allows us to convert an Object to stream that we can send over the network or save it as file or store in DB for later usage.
获得对象深层副本的一种方法是使用序列化 。 只是为了进行修改,Java中的序列化允许我们将对象转换为流,可以通过网络发送该流,也可以将其保存为文件或存储在DB中以备后用。
Let’s keep that in mind and hover over the basic idea behind deep copy in Java.
让我们牢记这一点,并将其悬停在Java深层复制背后的基本思想上。
The basic idea behind deep copy in java is:
Java深层复制背后的基本思想是:
- There is a Java object which is needed to be cloned (deeply). 有一个Java对象需要被(深度)克隆。
- First step is to mark the Model object as Serializable so that the object can converted into a Stream so that it can be written in a file/stream ond can be read back. 第一步是将Model对象标记为Serializable,以便将该对象转换为Stream,以便可以将其写入文件/流ond并可以回读。
- When the object is read back, we get a deep clone of the original object. 读回对象后,我们将获得原始对象的深层克隆。
- Note that this method works fine when the class you want to deep copy is serializable and all of it’s variables are also Serializable. Otherwise it will not work and you will get
java.io.NotSerializableException
. 请注意,当要深度复制的类可序列化并且其所有变量也可序列化时,此方法可以正常工作。 否则它将无法正常工作,并且您将获得java.io.NotSerializableException
。 - If the classes are not serializable, then the only option is to write a custom method to take care of copying object variables field by field to get a deep copy. 如果这些类不可序列化,则唯一的选择是编写一个自定义方法,以逐个字段复制对象变量以获取深层副本。
如何进行深度复制? (How to do Deep Copy?)
Now that was the process through which we can deep copy of an object is outlined. Let’s see how it’s done programmatically:
现在就是概述对象深层复制的过程。 让我们看看它是如何以编程方式完成的:
/**
* 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;
}
}
Above method accepts an Object and return its deep copy.
上面的方法接受一个Object并返回其深层副本。
This method is a ready-to-use method. It can be called as:
此方法是即用型方法。 可以称为:
//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);
深拷贝与浅拷贝 (Deep Copy vs Shallow Copy)
As we saw, deep copy is a pretty simple concept but still, it is confused with terms like shallow copy of an Object.
如我们所见,深层复制是一个非常简单的概念,但仍然与诸如对象的浅层复制之类的术语混淆。
It is important to understand that a shallow copy is just another reference to the same Object. Let’s see through code how a Shallow Copy can be made for an Object:
重要的是要了解,浅表副本只是对同一对象的另一个引用。 让我们看一下代码如何为对象创建浅拷贝:
List firstList, secondList;
firstList = new ArrayList();
firstList.add("Hello:);
secondList = firstList;
secondList.add("World");
In above example, the statement secondList = firstList;
makes a shallow copy of the firstList. When the second element is added to the secondList, it also means that the firstList contains two elements as well because both the lists are actually the same.
在上面的示例中,语句secondList = firstList;
制作firstList的浅表副本。 当第二个元素添加到secondList时,这也意味着firstList也包含两个元素,因为两个列表实际上是相同的 。
对象clone()方法 (Object clone() method)
Object clone() method is generally thought to produce a copy of the target object.
通常认为对象clone()方法可生成目标对象的副本。
Here’s what the javadoc says:
这是javadoc所说的:
Note, that this states that at one side the clone might be the target object, and at the other side the clone might not even be equal to the actual object. And this assumes if clone is even supported.
请注意,这表明克隆的一侧可能是目标对象,而另一侧的克隆甚至可能不等于实际对象。 并假设是否甚至支持克隆。
To summarise, the clone can mean significantly different for every Java class.
总而言之,对于每个Java类,克隆都可能意味着显着不同。
结论 (Conclusion)
In this lesson, we looked on how to implement java deep copy for an Object. We also cleared some ill-understanding between cloning and Shallow copy of objects and defined what clone() method in Java actually refers to.
在本课程中,我们研究了如何为对象实现Java深层复制。 我们还清除了克隆和对象的浅表副本之间的一些误解,并定义了Java中的clone()方法实际上指的是什么。
java 对象深度复制