public final class PropertyUtil extends Object
PropertyUtils的再次封装.
- 目的是将原来的 checkedException 异常 转换成
BeanOperationException
PropertyUtils与 BeanUtils:
PropertyUtils类和BeanUtils类很多的方法在参数上都是相同的,但返回值不同.
BeanUtils着重于"Bean",返回值通常是String,
而PropertyUtils着重于属性,它的返回值通常是Object.
PropertyUtils,
BeanUtil| Modifier and Type | Method and Description |
|---|---|
static void |
copyProperties(Object toObj,
Object fromObj,
String... includePropertyNames)
将
fromObj 中的全部或者一组属性的值,复制到 toObj 对象中. |
static Map<String,Object> |
describe(Object bean,
String... propertyNames)
|
static <T> T |
findValueOfType(Object obj,
Class<T> toBeFindedClassType)
从指定的
obj中,查找指定类型 toBeFindedClassType 的值. |
static <T> T |
getProperty(Object bean,
String propertyName)
使用
PropertyUtils.getProperty(Object, String) 从指定bean对象中取得指定属性名称的值. |
static void |
setProperty(Object bean,
String propertyName,
Object value)
使用
PropertyUtils.setProperty(Object, String, Object) 来设置指定bean对象中的指定属性的值. |
static void |
setPropertyIfValueNotNull(Object bean,
String propertyName,
Object value)
如果
null != value,那么才调用 setProperty(Object, String, Object). |
static void |
setPropertyIfValueNotNullOrEmpty(Object bean,
String propertyName,
Object value)
如果
value isNotNullOrEmpty,那么才调用 setProperty(Object, String, Object). |
public static void copyProperties(Object toObj, Object fromObj, String... includePropertyNames)
fromObj 中的全部或者一组属性的值,复制到 toObj 对象中.
- 如果
toObj是null,抛出NullPointerException- 如果
fromObj是null,抛出NullPointerException- 对于Date类型,不需要先注册converter
- 这种copy都是 浅拷贝,复制后的2个Bean的同一个属性可能拥有同一个对象的ref,这个在使用时要小心,特别是对于属性为自定义类的情况 .
User oldUser = new User(); oldUser.setId(5L); oldUser.setMoney(new BigDecimal(500000)); oldUser.setDate(now()); oldUser.setNickName(ConvertUtil.toArray("feilong", "飞天奔月", "venusdrogon")); User newUser = new User(); PropertyUtil.copyProperties(newUser, oldUser, "date", "money", "nickName"); LOGGER.debug(JsonUtil.format(newUser));返回:{ "date": "2015-09-06 13:27:43", "id": 0, "nickName": [ "feilong", "飞天奔月", "venusdrogon" ], "age": 0, "name": "feilong", "money": 500000, "userInfo": {"age": 0} }
对于以下代码:
private ContactCommand toContactCommand(ShippingInfoSubForm shippingInfoSubForm){ ContactCommand contactCommand = new ContactCommand(); contactCommand.setCountryId(shippingInfoSubForm.getCountryId()); contactCommand.setProvinceId(shippingInfoSubForm.getProvinceId()); contactCommand.setCityId(shippingInfoSubForm.getCityId()); contactCommand.setAreaId(shippingInfoSubForm.getAreaId()); contactCommand.setTownId(shippingInfoSubForm.getTownId()); return contactCommand; }可以重构成:private ContactCommand toContactCommand(ShippingInfoSubForm shippingInfoSubForm){ ContactCommand contactCommand = new ContactCommand(); PropertyUtil.copyProperties(contactCommand, shippingInfoSubForm, "countryId", "provinceId", "cityId", "areaId", "townId"); return contactCommand; }可以看出,代码更精简,目的性更明确
BeanUtils.copyProperties(Object, Object)与 PropertyUtils.copyProperties(Object, Object)区别
BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,
而PropertyUtils不支持这个功能,但是速度会更快一些.- commons-beanutils v1.9.0以前的版本 BeanUtils不允许对象的属性值为 null,PropertyUtils可以拷贝属性值 null的对象.
(注:commons-beanutils v1.9.0+修复了这个情况,BeanUtilsBean.copyProperties() no longer throws a ConversionException for null properties of certain data types),具体参阅commons-beanutils的 RELEASE-NOTES.txt
PropertyUtils.copyProperties(Object, Object)的优点:
- 将 checkedException 异常转成了
BeanOperationExceptionRuntimeException,因为通常copy的时候出现了checkedException,也是普普通通记录下log,没有更好的处理方式- 支持 includePropertyNames 参数,允许针对性copy 个别属性
- 更多,更容易理解的的javadoc
toObj - 目标对象fromObj - 原始对象includePropertyNames - 包含的属性数组名字数组,(can be nested/indexed/mapped/combo)PropertyUtils.copyProperties(Object, Object)includePropertyNames参数,那么直接调用PropertyUtils.copyProperties(Object, Object),否则循环调用
getProperty(Object, String)再setProperty(Object, String, Object)到toObj对象中includePropertyNames,含有 fromObj没有的属性名字,将会抛出异常includePropertyNames,含有 fromObj有,但是 toObj没有的属性名字,会抛出异常,see
copyProperties Line2078NullPointerException - 如果 toObj 是null,或者 fromObj 是nullBeanOperationException - 如果在copy的过程中,有任何的checkedException,将会被转成该异常返回setProperty(Object, String, Object),
BeanUtil.copyProperties(Object, Object, String...),
PropertyUtilsBean.copyProperties(Object, Object),
Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring
BeanUtils,Cglib BeanCopier)public static Map<String,Object> describe(Object bean, String... propertyNames)
bean中指定属性 propertyNames可读属性,并将属性名/属性值放入一个
LinkedHashMap 中.
场景: 取到user bean里面所有的属性成map
User user = new User(); user.setId(5L); user.setDate(now()); LOGGER.debug(JsonUtil.format(PropertyUtil.describe(user));返回:{ "id": 5, "name": "feilong", "age": null, "date": "2016-07-13 22:18:26" }
场景: 提取user bean "date"和 "id"属性:
User user = new User(); user.setId(5L); user.setDate(now()); LOGGER.debug(JsonUtil.format(PropertyUtil.describe(user, "date", "id"));返回的结果,按照指定参数名称顺序:{ "date": "2016-07-13 22:21:24", "id": 5 }
- 另外还有一个名为class的属性,属性值是Object的类名,事实上class是java.lang.Object的一个属性
- 如果
propertyNames是null或者 empty,那么获取所有属性的值- map的key按照
propertyNames的顺序
- 取到bean class的
PropertyDescriptor数组- 循环,找到
PropertyDescriptor.getReadMethod()- 将 name and
PropertyUtilsBean.getProperty(Object, String)设置到map中
bean - Bean whose properties are to be extractedpropertyNames - 属性名称 (can be nested/indexed/mapped/combo),参见 propertyNamepropertyNames 是null或者empty,返回 PropertyUtils.describe(Object)NullPointerException - 如果 bean 是null,或者propertyNames 包含 null的元素IllegalArgumentException - 如果 propertyNames 包含 blank的元素BeanUtils.describe(Object),
PropertyUtils.describe(Object)public static void setProperty(Object bean, String propertyName, Object value)
PropertyUtils.setProperty(Object, String, Object) 来设置指定bean对象中的指定属性的值.
- 不会进行类型转换
User newUser = new User(); PropertyUtil.setProperty(newUser, "name", "feilong"); LOGGER.info(JsonUtil.format(newUser));返回:{ "age": 0, "name": "feilong" }
- 如果
bean是null,抛出NullPointerException- 如果
propertyName是null,抛出NullPointerException- 如果
propertyName是blank,抛出IllegalArgumentException- 如果
bean没有传入的propertyName属性名字,会抛出异常,seesetSimplePropertyLine2078,转成BeanOperationException- 对于Date类型,不需要先注册converter
bean - Bean whose property is to be modifiedpropertyName - 属性名称 (can be nested/indexed/mapped/combo),参见 propertyNamevalue - Value to which this property is to be setBeanUtils.setProperty(Object, String, Object),
PropertyUtils.setProperty(Object, String, Object),
BeanUtil.setProperty(Object, String, Object)public static void setPropertyIfValueNotNullOrEmpty(Object bean, String propertyName, Object value)
value isNotNullOrEmpty,那么才调用 setProperty(Object, String, Object).
- 如果
bean是null,抛出NullPointerException- 如果
propertyName是null,抛出NullPointerException- 如果
propertyName是blank,抛出IllegalArgumentException- 如果
bean没有传入的propertyName属性名字,会抛出异常,seePropertyUtilsBean.setSimpleProperty(Object, String, Object)Line2078- 对于Date类型,不需要先注册converter
bean - Bean whose property is to be modifiedpropertyName - 属性名称 (can be nested/indexed/mapped/combo),参见 propertyNamevalue - Value to which this property is to be setpublic static void setPropertyIfValueNotNull(Object bean, String propertyName, Object value)
null != value,那么才调用 setProperty(Object, String, Object).
- 如果
bean是null,抛出NullPointerException- 如果
propertyName是null,抛出NullPointerException- 如果
propertyName是blank,抛出IllegalArgumentException- 如果
bean没有传入的propertyName属性名字,会抛出异常,seePropertyUtilsBean.setSimpleProperty(Object, String, Object)Line2078- 对于Date类型,不需要先注册converter
bean - Bean whose property is to be modifiedpropertyName - 属性名称 (can be nested/indexed/mapped/combo),参见 propertyNamevalue - Value to which this property is to be setsetProperty(Object, String, Object)public static <T> T getProperty(Object bean, String propertyName)
PropertyUtils.getProperty(Object, String) 从指定bean对象中取得指定属性名称的值.
- 原样取出值,不会进行类型转换.
场景: 取list中第一个元素的id
User user = new User(); user.setId(5L); user.setDate(now()); List返回:<User>list = toList(user, user, user); Long id = PropertyUtil.getProperty(list, "[0].id");5
T - the generic typebean - Bean whose property is to be extractedpropertyName - 属性名称 (can be nested/indexed/mapped/combo),参见 propertyNamebean 是null,抛出 NullPointerExceptionpropertyName 是null,抛出 NullPointerExceptionpropertyName 是blank,抛出 IllegalArgumentExceptionPropertyUtils.getProperty(Object, String) 从对象中取得属性值BeanUtil.getProperty(Object, String),
BeanUtils.getProperty(Object, String),
PropertyUtils.getProperty(Object, String),
PropertyUtilsBeanpublic static <T> T findValueOfType(Object obj, Class<T> toBeFindedClassType)
obj中,查找指定类型 toBeFindedClassType 的值.
- 如果
ClassUtil.isInstance(obj, toBeFindedClassType)直接返回 findValue- 不支持obj是
isPrimitiveOrWrapper,CharSequence,Collection,Map类型,自动过滤- 调用
describe(Object, String...)再递归查找- 目前暂不支持从集合里面找到指定类型的值,如果你有相关需求,可以调用 "org.springframework.util.CollectionUtils#findValueOfType(Collection, Class)"
场景: 从User中找到UserInfo类型的值
User user = new User(); user.setId(5L); user.setDate(now()); user.getUserInfo().setAge(28); LOGGER.info(JsonUtil.format(PropertyUtil.findValueOfType(user, UserInfo.class)));返回:{"age": 28}
T - the generic typeobj - 要被查找的对象toBeFindedClassType - the to be finded class typeobj 是null或者是empty,返回nulltoBeFindedClassType 是null,抛出 NullPointerExceptionClassUtil.isInstance(obj, toBeFindedClassType),直接返回 objnullCopyright © 2008-2019 by feilong