java序列化深克隆
这有时会导致问题。 例如,如果您想深克隆一个不提供合适克隆方法的对象,除了编写大量代码之外,您还有什么选择?
通过序列化克隆
最简单的方法是通过利用对象可序列化进行克隆。 Apache Commons提供了一种执行此操作的方法,但是为了完整起见,下面也是您自己执行此操作的代码。
@SuppressWarnings("unchecked")
public static T cloneThroughSerialize(T t) throws Exception {ByteArrayOutputStream bos = new ByteArrayOutputStream();serializeToOutputStream(t, bos);byte[] bytes = bos.toByteArray();ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));return (T)ois.readObject();
}private static void serializeToOutputStream(Serializable ser, OutputStream os)throws IOException {ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(os);oos.writeObject(ser);oos.flush();} finally {oos.close();}
}// using our custom method
Object cloned = cloneThroughSerialize (someObject);// or with Apache Commons
cloned = org.apache.commons.lang. SerializationUtils.clone(someObject);
但是,如果我们要克隆的类不是可序列化的,并且我们无法控制源代码或者无法将其设置为可序列化该怎么办?
选项1 – Java深度克隆库
有一个不错的小程序库,它可以深度克隆几乎所有Java对象- 克隆 。 它利用Java的出色反射功能来提供优化的对象的深克隆版本。
Cloner cloner=new Cloner();
Object cloned = cloner.deepClone(someObject);
如您所见,它非常简单有效,并且需要最少的代码。 除了这个简单的示例,它还具有一些更高级的功能,您可以在此处查看 。
选项2 – JSON克隆
如果我们无法将新库引入我们的代码库,该怎么办? 我们中有些人处理批准程序以引入新的库,对于一个简单的用例,可能不值得。
好吧,只要我们有某种方式可以序列化和还原对象,就可以进行深层复制。 JSON通常被使用,因此它是一个很好的选择,因为我们大多数人都使用一个或另一个JSON库。
Java中的大多数JSON库都可以有效地序列化任何POJO,而无需任何配置或映射。 这意味着,如果您具有JSON库并且不能或不会引入更多库来提供深度克隆,则可以利用现有的JSON库来获得相同的效果。 请注意,此方法将比其他方法慢,但是对于绝大多数应用程序,这不会引起任何性能问题。
以下是使用GSON库的示例。
@SuppressWarnings("unchecked")
public static T cloneThroughJson(T t) {Gson gson = new Gson();String json = gson.toJson(t);return (T) gson.fromJson(json, t.getClass());
}
// ...
Object cloned = cloneThroughJson(someObject);
请注意,仅当复制的对象具有默认的无参数构造函数时,这才可能起作用。 对于GSON,您可以使用实例创建者来解决此问题。 其他框架具有类似的概念,因此如果遇到无法修改的类且没有默认构造函数的问题,则可以使用该框架。
结论
我建议做的一件事是,对于需要克隆的任何类,都应该添加一些单元测试,以确保一切正常。 这可以防止对类的更改(例如,升级库版本)在您不知情的情况下破坏应用程序,尤其是在您设置了持续集成环境的情况下。
我概述了几种在没有任何自定义代码的情况下克隆对象的方法。 如果您使用其他任何方法获得相同的结果,请分享。
参考: Carfey Software Blog上的JCG合作伙伴 Craig Flichel从Java轻松深度克隆了Java中的可序列化和不可序列化的对象 。
相关文章 :
- Java最佳实践–高性能序列化
- 使用Gson教程进行Android JSON解析
- 在您的GWT应用程序中添加JSON功能
- Java 7功能概述
- Java Code Geeks编写的Java示例和代码段–正式发布
翻译自: https://www.javacodegeeks.com/2011/12/cloning-of-serializable-and-non.html
java序列化深克隆