实现深度对象复制函数有点困难。您采取什么步骤来确保原始对象和克隆对象没有共享引用?
当前回答
一个安全的方法是序列化对象,然后反序列化。这确保了所有内容都是全新的参考。
这里有一篇关于如何有效地做到这一点的文章。
注意:类可以重写序列化,这样就不会创建新的实例,例如单例。当然,如果你的类不是序列化的,这也行不通。
其他回答
BeanUtils在深度克隆bean方面做得非常好。
BeanUtils.cloneBean(obj);
深度复制只能在每个班级同意的情况下进行。如果您可以控制类层次结构,那么您可以实现可克隆接口并实现Clone方法。否则进行深度复制是不可能安全的,因为对象也可能共享非数据资源(例如数据库连接)。一般来说,深度复制在Java环境中被认为是不好的做法,应该通过适当的设计实践来避免。
一个非常快速和简单的一行程序解决方案是使用Jackson。
看一下示例代码片段:
ObjectMapper objectMapper = new ObjectMapper();
MyClass deepCopyObject = objectMapper
.readValue(objectMapper.writeValueAsString(originalObject), MyClass.class);
在上面的例子中:“MyClass”指的是你想要复制的对象的类。
解释:我们只是试图将原始对象序列化为字符串,然后将字符串反序列化回对象,从而获得一个深度副本。 了解更多关于ObjectMapper的信息,请访问:https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html
import com.thoughtworks.xstream.XStream;
public class deepCopy {
private static XStream xstream = new XStream();
//serialize with Xstream them deserialize ...
public static Object deepCopy(Object obj){
return xstream.fromXML(xstream.toXML(obj));
}
}
您可以使用序列化进行深度复制,而无需创建文件。
您希望深度复制的对象需要实现可序列化。如果类不是final或不能修改,则扩展类并实现serializable。
将你的类转换为字节流:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(object);
oos.flush();
oos.close();
bos.close();
byte[] byteData = bos.toByteArray();
从字节流中恢复类:
ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
Object object = new ObjectInputStream(bais).readObject();
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap