递归地将属性从一个 bean 复制到另一个(不相同 class)(包括嵌套 bean)
Copy properties from one bean to another (not the same class) recursively (including nested beans)
哪种方法需要最少的自己编写的代码来实现一个 bean 到另一个 bean 的深度复制?目标是在源属性和目标属性按名称匹配时以自动方式执行此操作。
源主 bean:
public class SourceBean {
private String beanField;
private SourceNestedBean nestedBean;
// getters and setters
}
源嵌套 bean:
public class SourceNestedBean {
private String nestedBeanField;
// getters and setters
}
目标主 bean:
public class TargetBean {
private String beanField;
private TargetNestedBean nestedBean;
// getters and setters
}
目标嵌套 bean:
public class TargetNestedBean {
private String nestedBeanField;
// getters and setters
}
使用例如Spring BeanUtils.copyProperites() 我可以用一行代码创建 SourceBean
到 TargetBean
的浅表副本,但它不会复制嵌套的 bean。是否有任何成熟的实用程序(不一定 Spring 框架)允许在 编写尽可能少的自己的代码时进行深度复制 (与 [=35= 几乎相同) ]())?
而如果你想在 Java 中使用深度复制,你应该使用 ObjectOutputStream 和 ObjectInputStream,你需要复制的所有 class 应该实现 Serializable。
public Object deepCopy() throws IOException, ClassNotFoundException{
//store object in memory using serial
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
使用 apache commons-lang 中的 SerializationUtils。并使您的对象可序列化。
您可以使用Dozer Mapper 进行深拷贝。参见 http://dozer.sourceforge.net/documentation/deepmapping.html
一种方法是 Jackson ObjectMapper
, via the convertValue()
method:
ObjectMapper mapper = new ObjectMapper();
SourceBean source = ...;
TargetBean target = mapper.convertValue(source, TargetBean.class);
请注意,convertValue()
已重载以也适用于泛型类型。还要注意 convertValue()
在某些情况下会 return 您提供的值,例如如果 SourceBean 可分配给 TargetBean。
由于 Jackson 是一个 JSON serialization/deserialization 库,convertValue()
所做的是在内存中将 source
序列化为 JSON,然后反序列化此 JSON 到 TargetBean
的一个实例中。所以高性能是不可期待的。但是,转换是用一行代码执行的。
如果需要性能,最好是手动映射。没有比这更好的了。
如果您需要简单性,请如上所述使用 Jackson。
一个很好的权衡是 Orika,一个高性能的映射器,几乎没有配置,不使用反射。
哪种方法需要最少的自己编写的代码来实现一个 bean 到另一个 bean 的深度复制?目标是在源属性和目标属性按名称匹配时以自动方式执行此操作。
源主 bean:
public class SourceBean {
private String beanField;
private SourceNestedBean nestedBean;
// getters and setters
}
源嵌套 bean:
public class SourceNestedBean {
private String nestedBeanField;
// getters and setters
}
目标主 bean:
public class TargetBean {
private String beanField;
private TargetNestedBean nestedBean;
// getters and setters
}
目标嵌套 bean:
public class TargetNestedBean {
private String nestedBeanField;
// getters and setters
}
使用例如Spring BeanUtils.copyProperites() 我可以用一行代码创建 SourceBean
到 TargetBean
的浅表副本,但它不会复制嵌套的 bean。是否有任何成熟的实用程序(不一定 Spring 框架)允许在 编写尽可能少的自己的代码时进行深度复制 (与 [=35= 几乎相同) ]())?
而如果你想在 Java 中使用深度复制,你应该使用 ObjectOutputStream 和 ObjectInputStream,你需要复制的所有 class 应该实现 Serializable。
public Object deepCopy() throws IOException, ClassNotFoundException{
//store object in memory using serial
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
使用 apache commons-lang 中的 SerializationUtils。并使您的对象可序列化。
您可以使用Dozer Mapper 进行深拷贝。参见 http://dozer.sourceforge.net/documentation/deepmapping.html
一种方法是 Jackson ObjectMapper
, via the convertValue()
method:
ObjectMapper mapper = new ObjectMapper();
SourceBean source = ...;
TargetBean target = mapper.convertValue(source, TargetBean.class);
请注意,convertValue()
已重载以也适用于泛型类型。还要注意 convertValue()
在某些情况下会 return 您提供的值,例如如果 SourceBean 可分配给 TargetBean。
由于 Jackson 是一个 JSON serialization/deserialization 库,convertValue()
所做的是在内存中将 source
序列化为 JSON,然后反序列化此 JSON 到 TargetBean
的一个实例中。所以高性能是不可期待的。但是,转换是用一行代码执行的。
如果需要性能,最好是手动映射。没有比这更好的了。
如果您需要简单性,请如上所述使用 Jackson。
一个很好的权衡是 Orika,一个高性能的映射器,几乎没有配置,不使用反射。