这有时会导致问题。 例如,如果您想深度克隆不提供合适克隆方法的对象,除了编写大量代码之外,您还有什么选择?
通过序列化克隆
最简单的方法是通过利用对象可序列化进行克隆。 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中的可序列化和不可序列化的对象 。
相关文章 :
翻译自: https://www.javacodegeeks.com/2011/12/cloning-of-serializable-and-non.html