实现深度对象复制函数有点困难。您采取什么步骤来确保原始对象和克隆对象没有共享引用?
当前回答
适用于Spring框架用户。使用类org.springframework.util.SerializationUtils:
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T object) {
return (T) SerializationUtils.deserialize(SerializationUtils.serialize(object));
}
其他回答
这是一个关于如何深度克隆任何对象的简单示例: 首先实现serializable
public class CSVTable implements Serializable{
Table<Integer, Integer, String> table;
public CSVTable() {
this.table = HashBasedTable.create();
}
public CSVTable deepClone() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (CSVTable) ois.readObject();
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
}
然后
CSVTable table = new CSVTable();
CSVTable tempTable = table.deepClone();
才能得到克隆体。
一个安全的方法是序列化对象,然后反序列化。这确保了所有内容都是全新的参考。
这里有一篇关于如何有效地做到这一点的文章。
注意:类可以重写序列化,这样就不会创建新的实例,例如单例。当然,如果你的类不是序列化的,这也行不通。
一个非常快速和简单的一行程序解决方案是使用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
BeanUtils在深度克隆bean方面做得非常好。
BeanUtils.cloneBean(obj);
深度复制只能在每个班级同意的情况下进行。如果您可以控制类层次结构,那么您可以实现可克隆接口并实现Clone方法。否则进行深度复制是不可能安全的,因为对象也可能共享非数据资源(例如数据库连接)。一般来说,深度复制在Java环境中被认为是不好的做法,应该通过适当的设计实践来避免。
推荐文章
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?