原文: https://howtodoinjava.com/java/serialization/how-to-do-deep-cloning-using-in-memory-serialization-in-java/

众所周知,深度克隆(和某些性能开销)或深层复制的最简单方法是序列化。 Java 序列化涉及将对象序列化为字节,然后再次从字节序列化为对象。

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

请记住,对于单例模式来说,深克隆是邪恶的。 它使拥有多个单例类实例成为可能。

阅读更多: Java 对象克隆指南

1. Java 深层复制示例

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

对于深度克隆,我们必须先进行序列化,然后进行反序列化。 对于序列化,我使用了 ByteArrayOutputStreamObjectOutputStream。 对于反序列化,我使用了ByteArrayInputStreamObjectInputStream

  1. package serializationTest;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.ObjectInputStream;
  5. import java.io.ObjectOutputStream;
  6. import java.io.Serializable;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class SerializableClass implements Serializable
  10. {
  11. private static final long serialVersionUID = 1L;
  12. private String firstName = null;
  13. private String lastName = null;
  14. @SuppressWarnings("serial")
  15. private List permissions = new ArrayList()
  16. {
  17. {
  18. add("ADMIN");
  19. add("USER");
  20. }
  21. };
  22. public SerializableClass(final String fName, final String lName)
  23. {
  24. //validateNameParts(fName);
  25. //validateNameParts(lName);
  26. this.firstName = fName;
  27. this.lastName = lName;
  28. }
  29. public SerializableClass deepCopy() throws Exception
  30. {
  31. //Serialization of object
  32. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  33. ObjectOutputStream out = new ObjectOutputStream(bos);
  34. out.writeObject(this);
  35. //De-serialization of object
  36. ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
  37. ObjectInputStream in = new ObjectInputStream(bis);
  38. SerializableClass copied = (SerializableClass) in.readObject();
  39. //Verify that object is not corrupt
  40. //validateNameParts(fName);
  41. //validateNameParts(lName);
  42. return copied;
  43. }
  44. public String getFirstName() {
  45. return firstName;
  46. }
  47. public void setFirstName(String firstName) {
  48. this.firstName = firstName;
  49. }
  50. public String getLastName() {
  51. return lastName;
  52. }
  53. public void setLastName(String lastName) {
  54. this.lastName = lastName;
  55. }
  56. @Override
  57. public String toString() {
  58. return new StringBuilder().append(getFirstName()+",")
  59. .append(getLastName()+",")
  60. .append(permissions)
  61. .toString();
  62. }
  63. }

2. 演示

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

  1. package serializationTest;
  2. public class ImMemoryTest
  3. {
  4. public static void main(String[] args) throws Exception
  5. {
  6. //Create instance of serializable object
  7. SerializableClass myClass = new SerializableClass("Lokesh","Gupta");
  8. //Verify the content
  9. System.out.println(myClass);
  10. //Now create a deep copy of it
  11. SerializableClass deepCopiedInstance = myClass.deepCopy();
  12. //Again verify the content
  13. System.out.println(deepCopiedInstance);
  14. }
  15. }

程序输出。

  1. Lokesh,Gupta,[ADMIN, USER]
  2. Lokesh,Gupta,[ADMIN, USER]

在考虑应用程序中的内存深层复制对象之前,您可能需要阅读有关序列化指南的信息,这将防止将来的设计中断。

学习愉快!

阅读更多:

Java 中的浅表副本与深表副本