SerializationUtils
总是会产生一个deep -copy。它将为每个字段创建一个字符串(称为序列化)并将字符串解析回一个新对象(反序列化)。
这很慢,但是您可以保证您的副本是深层副本。
深拷贝意味着:所有字段都是新对象(而不是对旧对象的引用)。
BeanUtils.cloneBean()
另一方面,将创建对象的浅表副本。这是一些代码来解释有什么区别:
@Data // lombok annotation, will create getters, setters, equals and hashcode
public class ObjectA implements Serializeable {
private List<String> values = new ArrayList<>();
}
public static main() {
ObjectA objectA = new ObjectA();
objectA().getValues().add("A");
ObjectA beanClone = (ObjectA) BeanUtils.cloneBean(objectA);
ObjectA serialClone = SerializationUtils.clone(objectA);
log.info("Reference-Check: Bean is same: {}", objectA == beanClone); // <- false
log.info("Reference-Check: Bean-Value is same: {}", objectA.getValues() == beanClone.getValues()); // <- true
log.info("Reference-Check: Serial is same: {}", objectA == serialClone); // <- false
log.info("Reference-Check: Serial-Value is same: {}", objectA.getValues() == serialClone.getValues()); // <- false
serialClone.getValues().add("B");
printValues(serialClone.getValues()); // <- prints "['A', 'B']"
printValues(objectA.getValues()); // <- prints "['A']";
beanClone.getValues().add("B");
printValues(beanClone.getValues()); // <- prints "['A', 'B']"
printValues(objectA.getValues()); // <- prints "['A', 'B']"
}
所以对于你的问题:深拷贝“更安全”,你不能修改原始对象的字段。这种对浅拷贝的副作用通常是不需要的。几乎总是,你需要一个深拷贝。
序列化非常慢,所以最好的方法是复制方法或复制构造函数。