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 异常转成了
BeanOperationException
RuntimeException,因为通常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
属性名字,会抛出异常,seesetSimpleProperty
Line2078,转成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,抛出 NullPointerException
propertyName
是null,抛出 NullPointerException
propertyName
是blank,抛出 IllegalArgumentException
PropertyUtils.getProperty(Object, String)
从对象中取得属性值BeanUtil.getProperty(Object, String)
,
BeanUtils.getProperty(Object, String)
,
PropertyUtils.getProperty(Object, String)
,
PropertyUtilsBean
public 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,抛出 NullPointerException
ClassUtil.isInstance(obj, toBeFindedClassType)
,直接返回 obj
null
Copyright © 2008-2019 by feilong