# 使用内存序列化的 Java 深层复制

> 原文： [https://howtodoinjava.com/java/serialization/how-to-do-deep-cloning-using-in-memory-serialization-in-java/](https://howtodoinjava.com/java/serialization/how-to-do-deep-cloning-using-in-memory-serialization-in-java/)

众所周知，深度克隆（*和某些性能开销*）或深层复制的最简单方法是[序列化](https://howtodoinjava.com/java/serialization/a-mini-guide-for-implementing-serializable-interface-in-java/)。 Java 序列化涉及将对象序列化为字节，然后再次从字节序列化为对象。

我建议您在仅仅需要它且不需要持久保存对象以备将来使用的情况下，使用内存深度克隆。 在这个 Java 深度克隆示例中，我将提出一种内存中深度克隆的机制供您参考。

请记住，对于[**单例模式**](//howtodoinjava.com/design-patterns/singleton-design-pattern-in-java/ "Singleton design pattern in java")来说，深克隆是邪恶的。 它使拥有多个单例类实例成为可能。

> 阅读更多： [Java 对象克隆指南](//howtodoinjava.com/java/cloning/a-guide-to-object-cloning-in-java/ "A guide to object cloning in java")

## 1\. Java 深层复制示例

在演示程序中，我创建了一个名为`SerializableClass`的演示类。 这具有三个变量，即`firstName`，`lastName`和`permissions`。 我将向此类添加`deepCopy()`实例级方法。 每当在`SerializableClass`实例上调用时，它将返回该实例的精确克隆/深层副本。

对于深度克隆，我们必须先进行序列化，然后进行反序列化。 对于序列化，我使用了 [`ByteArrayOutputStream`](https://docs.oracle.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html "ByteArrayOutputStream") 和`ObjectOutputStream`。 对于反序列化，我使用了`ByteArrayInputStream`和`ObjectInputStream`。

```java
package serializationTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class SerializableClass implements Serializable
{

	private static final long serialVersionUID = 1L;

	private String firstName = null;
	private String lastName = null;

	@SuppressWarnings("serial")
	private List permissions = new ArrayList()
											{
												{
													add("ADMIN");
													add("USER");
												}
											};

	public SerializableClass(final String fName, final String lName)
	{
		//validateNameParts(fName);
		//validateNameParts(lName);
		this.firstName = fName;
		this.lastName = lName;
	}

	public SerializableClass deepCopy() throws Exception
    {
    	//Serialization of object
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(bos);
        out.writeObject(this);

        //De-serialization of object
        ByteArrayInputStream bis = new   ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream in = new ObjectInputStream(bis);
        SerializableClass copied = (SerializableClass) in.readObject();

        //Verify that object is not corrupt

        //validateNameParts(fName);
        //validateNameParts(lName);

        return copied;
    }

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return new StringBuilder().append(getFirstName()+",")
								  .append(getLastName()+",")
								  .append(permissions)
								  .toString();
	}
}

```

## 2\. 演示

让我们测试该类并创建实例的深层副本，以验证其是否按预期工作。

```java
package serializationTest;

public class ImMemoryTest 
{

    public static void main(String[] args) throws Exception 
    {
        //Create instance of serializable object
    	SerializableClass myClass = new SerializableClass("Lokesh","Gupta");

    	//Verify the content
    	System.out.println(myClass);

    	//Now create a deep copy of it
    	SerializableClass deepCopiedInstance = myClass.deepCopy();

       //Again verify the content
    	System.out.println(deepCopiedInstance);
    }
}

```

程序输出。

```java
Lokesh,Gupta,[ADMIN, USER]
Lokesh,Gupta,[ADMIN, USER]

```

在考虑应用程序中的**内存深层复制对象**之前，您可能需要阅读有关[**序列化指南**](//howtodoinjava.com/java/serialization/a-mini-guide-for-implementing-serializable-interface-in-java/ "A mini guide for implementing serializable interface in java")的信息，这将防止将来的设计中断。

学习愉快！

阅读更多：

[Java 中的浅表副本与深表副本](https://howtodoinjava.com/java/cloning/a-guide-to-object-cloning-in-java/)