BeanUtils.copyProperties 将 Integer null 转换为 0

2022-09-03 00:07:32

我注意到BeanUtils.copyProperties(dest,src)有一个奇怪的副作用。所有 null(可能等)在两个对象中都转换为 0:源(原文如此!)和目标。版本: commons-beanutils-1.7.0IntegersLongDate

javadoc:

对于属性名称相同的所有情况,将属性值从源 Bean 复制到目标 Bean。

例如:

class User {
   Integer age = null;
   // getters & setters
}
...
User userDest = new User();
User userSrc = new User();
BeanUtils.copyProperties(userDest, userSrc);
System.out.println(userDest.getAge()); // 0
System.out.println(userSrc.getAge()); // 0

源对象实际上被修改了,这可能非常错误。使用空值制作对象的“真实”副本的最佳解决方案是什么。


答案 1

好的,我找到了这篇文章

然而,我在使用这些类时遇到的这两个类之间存在很大差异:BeanUtils执行自动类型转换,而PropertyUtils不执行。

例如:使用BeanUtils,您可以通过提供字符串来设置双精度值属性。BeanUtils 将检查属性的类型,并将 String 转换为双精度值。使用 PropertyUtils,您始终必须提供与属性类型相同的值对象,因此在此示例中为双精度值。

在这种情况下,不需要自动转换,因此更好的选择是类PropertyUtils


答案 2

选中 http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/ConvertUtilsBean.html 它指示整数转换的默认值为 0。这是因为此处的目标类型是基元 int 或引用 int,而基元 int 不能设置为 null。

您可以覆盖 Integer 的转换器,并将其替换为默认值为 null 的转换器。

更新:用法是

import org.apache.commons.beanutils.converters.IntegerConverter;

IntegerConverter converter = new IntegerConverter(null); 
BeanUtilsBean beanUtilsBean = new BeanUtilsBean();
beanUtilsBean.getConvertUtils().register(converter, Integer.class);

查看 IntegerConverter 的源代码 - 在构造函数中设置默认值。