? ? ? ?commons-beanutils是Apache提供的一個用于操作JAVA bean的工具包熙含。里面提供了各種各樣的工具類禀综,讓我們可以很方便的對bean對象的屬性進行各種操作。
一 commons-beanutils依賴
? ? ? ?pom方式的引入(maven項目)奠伪。
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
二 commons-beanutils的使用
? ? ? ?關于commons-beanutils的使用主要是熟悉commons-beanutils庫里面MethodUtils掂墓、ConstructorUtils、PropertyUtils打掘、BeanUtils华畏、ConvertUtils的使用鹏秋。
2.1 MethodUtils
? ? ? ?MethodUtils通過反射對對象的方法做各種各樣的操作。
? ? ? ?MethodUtils提供的一些靜態(tài)方法:
方法 | 返回值 | 解釋 |
---|---|---|
setCacheMethods(final boolean cacheMethods) | void | 設置是否緩存方法(緩存可以提高性能) |
clearCache() | int | 清空方法緩存 |
invokeMethod(final Object object,final String methodName,final Object arg) | Object | 執(zhí)行方法 |
invokeMethod(final Object object,final String methodName,Object[] args) | Object | 執(zhí)行方法 |
invokeMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) | Object | 執(zhí)行方法 |
invokeExactMethod(final Object object,final String methodName,final Object arg) | Object | 執(zhí)行方法 |
invokeExactMethod(final Object object,final String methodName,Object[] args) | Object | 執(zhí)行方法 |
invokeExactMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) | Object | 執(zhí)行方法 |
invokeExactStaticMethod(final Object object,final String methodName,final Object arg) | Object | 執(zhí)行靜態(tài)方法 |
invokeExactStaticMethod(final Object object,final String methodName,Object[] args) | Object | 執(zhí)行靜態(tài)方法 |
invokeExactStaticMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) | Object | 執(zhí)行靜態(tài)方法 |
invokeStaticMethod(final Object object,final String methodName,final Object arg) | Object | 執(zhí)行靜態(tài)方法 |
invokeStaticMethod(final Object object,final String methodName,Object[] args) | Object | 執(zhí)行靜態(tài)方法 |
invokeStaticMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) | Object | 執(zhí)行靜態(tài)方法 |
getAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?> parameterType) | Method | 返回一個可訪問的方法 |
getAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?>[] parameterTypes) | Method | 返回一個可訪問的方法 |
getAccessibleMethod(final Method method) | Method | 返回一個可訪問的方法 |
getAccessibleMethod(Class<?> clazz, Method method) | Method | 返回一個可訪問的方法 |
getMatchingAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?>[] parameterTypes) | Method | 查找與方法名及參數(shù)匹配的可訪問方法 |
isAssignmentCompatible(final Class<?> parameterType, final Class<?> parameterization) | boolean | 確定是否可以使用一個類型作為方法調(diào)用參數(shù) |
getPrimitiveWrapper(final Class<?> primitiveType) | Class<?> | 獲得基本數(shù)據(jù)類型的包裝類型 |
getPrimitiveType(final Class<?> wrapperType) | Class<?> | 獲得包裝類的基本數(shù)據(jù)類型 |
toNonPrimitiveClass(final Class<?> clazz) | Class<?> | 如果是簡單數(shù)據(jù)類型則返回對應的包裝類亡笑,否則返回本身 |
? ? ? ?因為MethodUtils里面的方法都比較簡單侣夷,所以我們就不給出例子了。
2.2 ConstructorUtils
? ? ? ?ConstructorUtils通過反射對對象的構造方法做各種操作仑乌。
? ? ? ?ConstructorUtils提供的靜態(tài)方法:
方法名 | 返回值 | 解釋 |
---|---|---|
invokeConstructor(final Class<T> klass, final Object arg) | T | 執(zhí)行構造方法 |
invokeConstructor(final Class<T> klass, Object[] args) | T | 執(zhí)行構造方法 |
invokeConstructor(final Class<T> klass,Object[] args,Class<?>[] parameterTypes) | T | 執(zhí)行構造方法 |
invokeExactConstructor(final Class<T> klass, final Object arg) | T | 執(zhí)行構造方法 |
invokeExactConstructor(final Class<T> klass, Object[] args) | T | 執(zhí)行構造方法 |
invokeExactConstructor(final Class<T> klass,Object[] args,Class<?>[] parameterTypes) | T | 執(zhí)行構造方法 |
getAccessibleConstructor(final Class<T> klass,final Class<?> parameterType) | Constructor<T> | 獲得含有一個形參的構造方法 |
getAccessibleConstructor(final Class<T> klass,final Class<?>[] parameterTypes) | Constructor<T> | 獲得含有指定類型形參的構造方法 |
getAccessibleConstructor(final Constructor<T> ctor) | Constructor<T> | 獲得可訪問構造方法 |
? ? ? ?因為ConstructorUtils里面的方法都比較簡單百拓,所以我們就不給出例子了。
2.3 PropertyUtils
? ? ? ?PropertyUtils通過反射對對象的屬性做各種操作晰甚。
? ? ? ?PropertyUtils提供的靜態(tài)方法:
方法 | 返回值 | 解釋 |
---|---|---|
clearDescriptors() | void | 清空所有屬性描述信息 |
resetBeanIntrospectors() | void | 重置BeanIntrospector |
addBeanIntrospector(final BeanIntrospector introspector) | void | 添加一個BeanIntrospector |
removeBeanIntrospector(final BeanIntrospector introspector) | boolean | 移除BeanIntrospector |
copyProperties(final Object dest, final Object orig) | void | 復制屬性 |
describe(final Object bean) | Map<String, Object> | 屬性描述衙传,key屬性名,value屬性值 |
getIndexedProperty(final Object bean, final String name) | Object | 指定索引屬性值厕九,適用于屬性是list或者array的情況 |
getIndexedProperty(final Object bean,final String name, final int index) | Object | 指定索引屬性值蓖捶,適用于屬性是list或者array的情況 |
getMappedProperty(final Object bean, final String name) | Object | 獲得Map屬性,適用于屬性是Map的情況 |
getMappedProperty(final Object bean,final String name, final String key) | Object | 獲得Map屬性中指定鍵對應的值扁远,適用于屬性是Map的情況 |
getNestedProperty(final Object bean, final String name) | Object | 獲得嵌套屬性俊鱼,屬性是對象的情況 |
getProperty(final Object bean, final String name) | Object | 獲得屬性 |
getPropertyDescriptor(final Object bean,final String name) | PropertyDescriptor | 獲取屬性描述 |
getPropertyDescriptors(final Class<?> beanClass) | PropertyDescriptor[] | 獲得屬性描述 |
getPropertyDescriptors(final Object bean) | PropertyDescriptor[] | 獲得屬性描述 |
getPropertyEditorClass(final Object bean, final String name) | Class<?> | 獲得已為此屬性注冊的任何顯式 PropertyEditor Class |
getPropertyType(final Object bean, final String name) | Class<?> | 獲得屬性類型 |
getReadMethod(final PropertyDescriptor descriptor) | Method | 返回一個可訪問的屬性的getter方法 |
getSimpleProperty(final Object bean, final String name) | Object | 返回屬性值 |
getWriteMethod(final PropertyDescriptor descriptor) | Method | 返回一個可訪問的屬性的setter方法 |
isReadable(final Object bean, final String name) | boolean | 判斷是否為可讀屬性 |
isWriteable(final Object bean, final String name) | boolean | 判斷是否為可寫屬性 |
setIndexedProperty(final Object bean, final String name,final Object value) | void | 設置指定索引屬性值,適用于屬性是list或者array的情況 |
setIndexedProperty(final Object bean, final String name, final int index, final Object value) | void | 設置指定索引屬性值并闲,適用于屬性是list或者array的情況 |
setMappedProperty(final Object bean, final String name,final Object value) | void | 設置Map屬性的值 |
setMappedProperty(final Object bean, final String name, final String key, final Object value) | void | 設置Map屬性的值 |
setNestedProperty(final Object bean, final String name, final Object value) | void | 設置嵌套屬性的值 |
setProperty(final Object bean, final String name, final Object value) | void | 設置屬性值 |
setSimpleProperty(final Object bean, final String name, final Object value) | void | 設置屬性值 |
? ? ? ?PropertyUtils的使用帝火,如下實例。
public class PropertyUtilsTest {
public static class Address {
private String email;
public Address(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public static class UserInfo {
private String userName;
private int age;
private Address address;
private List<String> friendsNames;
private Map<String, String> tag;
UserInfo(String userName, int age, Address address, List<String> friendsNames, Map<String, String> tag) {
this.userName = userName;
this.age = age;
this.address = address;
this.friendsNames = friendsNames;
this.tag = tag;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getFriendsNames() {
return friendsNames;
}
public void setFriendsNames(List<String> friendsNames) {
this.friendsNames = friendsNames;
}
public Map<String, String> getTag() {
return tag;
}
public void setTag(Map<String, String> tag) {
this.tag = tag;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
@Test
public void test() {
List<String> friendList = Lists.newArrayList("張三", "李四");
Map<String, String> tag = Maps.newHashMap();
tag.put("key1", "value1");
tag.put("key2", "value2");
UserInfo userInfo = new UserInfo("tuacy", 18, new Address("1@qq.com"), friendList, tag);
try {
Map<String, Object> propertyMap = PropertyUtils.describe(userInfo);
Object friend0 = PropertyUtils.getIndexedProperty(userInfo, "friendsNames[0]"); // 張三
Object friend0Temp = PropertyUtils.getIndexedProperty(userInfo, "friendsNames", 0); // 張三
Object mapperProperty = PropertyUtils.getMappedProperty(userInfo, "tag(key1)"); // value1
Object mapperPropertyTemp = PropertyUtils.getMappedProperty(userInfo, "tag", "key1"); // value1
Object nestedProperty = PropertyUtils.getNestedProperty(userInfo, "address.email"); // 1@qq.com
Object name = PropertyUtils.getProperty(userInfo, "userName"); // tuacy
PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(userInfo, "userName"); // PropertyDescriptor是對屬性的一個封裝
PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(userInfo); // 獲取所有的屬性
Class<?> classType = PropertyUtils.getPropertyType(userInfo, "address"); // 獲取屬性的類型Address
Method getMethod = PropertyUtils.getReadMethod(PropertyUtils.getPropertyDescriptor(userInfo, "userName")); // getUserName()方法
Object simpleProperty = PropertyUtils.getSimpleProperty(userInfo, "userName");
Method setMethod = PropertyUtils.getWriteMethod(PropertyUtils.getPropertyDescriptor(userInfo, "userName")); // setUserName()方法
boolean isReadable = PropertyUtils.isReadable(userInfo, "userName"); // true
boolean isWriteable = PropertyUtils.isWriteable(userInfo, "userName"); // true
PropertyUtils.setIndexedProperty(userInfo, "friendsNames[0]", "張三第一次修改"); // 修改friendsNames第一個元素
PropertyUtils.setIndexedProperty(userInfo, "friendsNames", 0, "張三第二次修改"); // 修改friendsNames第一個元素
PropertyUtils.setMappedProperty(userInfo, "tag(key1)", "value1第一次修改"); // 修改tag key為key1的值
PropertyUtils.setMappedProperty(userInfo, "tag", "key1", "value1第二次修改"); // 修改tag key為key1的值
PropertyUtils.setNestedProperty(userInfo, "address.email", "1007@qq.com"); // 修改address屬性對象對應的email屬性
PropertyUtils.setProperty(userInfo, "userName", "tuacy0"); // 修改userName對應的屬性值
PropertyUtils.setSimpleProperty(userInfo, "age", 19); // 修改age對應的屬性值
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.4 BeanUtils
? ? ? ?BeanUtils通過反射提供了Bean對象的一些便捷操作方法购公。
? ? ? ?BeanUtils提供的靜態(tài)方法:
方法名 | 返回值 | 解釋 |
---|---|---|
cloneBean(final Object bean) | Object | 克隆對象 |
copyProperties(final Object dest, final Object orig) | void | 復制屬性 |
copyProperty(final Object bean, final String name, final Object value) | void | 復制屬性,相當于設置屬性 |
describe(final Object bean) | Map<String, String> | 描述 |
getArrayProperty(final Object bean, final String name) | String[] | 返回指定屬性的值靠瞎,作為字符串數(shù)組返回 |
getIndexedProperty(final Object bean, final String name) | String | 獲取指定索引位置對象作為字符串返回 |
getIndexedProperty(final Object bean,final String name, final int index) | String | 獲取指定索引位置對象作為字符串返回 |
getMappedProperty(final Object bean, final String name) | String | 獲得Map屬性值作為字符串返回 |
getMappedProperty(final Object bean, final String name, final String key) | String | 獲得Map屬性中指定鍵的值作為字符串返回 |
getNestedProperty(final Object bean, final String name) | String | 獲得嵌套屬性作為字符串返回 |
getProperty(final Object bean, final String name) | String | 獲得屬性值作為字符串返回 |
getSimpleProperty(final Object bean, final String name) | String | 獲得屬性值作為字符串返回 |
populate(final Object bean, final Map<String, ? extends Object> properties) | void | 將Map轉換成對象 |
setProperty(final Object bean, final String name, final Object value) | void | 設置屬性值 |
initCause(final Throwable throwable, final Throwable cause) | boolean | 對異常來進行包裝的 |
createCache() | Map<K, V> | 創(chuàng)建緩存 |
getCacheFast(final Map<?, ?> map) | boolean | |
setCacheFast(final Map<?, ?> map, final boolean fast) | void |
? ? ? ?BeanUtils的使用:
public class BeanUtilsTest {
public static class Address {
private String email;
public Address(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public static class UserInfo {
private String userName;
private int age;
private Address address;
private List<String> friendsNames;
private Map<String, String> tag;
public UserInfo() {
}
public UserInfo(String userName, int age, Address address, List<String> friendsNames, Map<String, String> tag) {
this.userName = userName;
this.age = age;
this.address = address;
this.friendsNames = friendsNames;
this.tag = tag;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getFriendsNames() {
return friendsNames;
}
public void setFriendsNames(List<String> friendsNames) {
this.friendsNames = friendsNames;
}
public Map<String, String> getTag() {
return tag;
}
public void setTag(Map<String, String> tag) {
this.tag = tag;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
@Test
public void test() {
List<String> friendList = Lists.newArrayList("張三", "李四");
Map<String, String> tag = Maps.newHashMap();
tag.put("key1", "value1");
tag.put("key2", "value2");
UserInfo userInfo = new UserInfo("tuacy", 18, new Address("1@qq.com"), friendList, tag);
try {
Object voClone = BeanUtils.cloneBean(userInfo);
UserInfo userInfo1 = new UserInfo();
BeanUtils.copyProperties(userInfo1, userInfo);
BeanUtils.copyProperty(userInfo1, "userName", "user1");
Map<String, String> map = BeanUtils.describe(userInfo); // 獲取所有的屬性名字和屬性對應的值比庄,注意這里值都會轉換成String
String[] arrays = BeanUtils.getArrayProperty(userInfo, "friendsNames"); // friendsNames數(shù)組轉換成數(shù)組
Object item = BeanUtils.getIndexedProperty(userInfo, "friendsNames[0]"); // 張三
Object itemItem = BeanUtils.getIndexedProperty(userInfo, "friendsNames", 0); // 張三
Object value = BeanUtils.getMappedProperty(userInfo, "tag(key1)"); // value1
Object valueValue = BeanUtils.getMappedProperty(userInfo, "tag", "key1"); // value1
Object email = BeanUtils.getNestedProperty(userInfo, "address.email"); // 1@qq.com
String userName = BeanUtils.getProperty(userInfo, "userName"); // tuacy
String userName0 = BeanUtils.getSimpleProperty(userInfo, "userName"); // tuacy
UserInfo userInfo2 = new UserInfo();
BeanUtils.populate(userInfo2, PropertyUtils.describe(userInfo)); // map轉換成對象
BeanUtils.setProperty(userInfo2, "userName", "tuacy0"); // map轉換成對象
NullPointerException nullPointerException = new NullPointerException("情況一");
NullPointerException nullPointerException1 = new NullPointerException("情況二");
BeanUtils.initCause(nullPointerException, nullPointerException1); // map轉換成對象
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.5 ConvertUtils
? ? ? ?ConvertUtils提供了數(shù)據(jù)類型相互轉換的一些方法。
? ? ? ?ConvertUtils靜態(tài)方法介紹:
方法名 | 返回值 | 解釋 |
---|---|---|
convert(final Object value) | String | 將對象轉換為字符串 |
convert(final String value, final Class<?> clazz) | Object | 將字符串轉換為指定數(shù)據(jù)類型對象 |
convert(final String[] values, final Class<?> clazz) | Object | 將數(shù)組轉換為指定數(shù)據(jù)類型對象 |
convert(final Object value, final Class<?> targetType) | Object | 將對象轉換為指定數(shù)據(jù)類型對象 |
deregister() | void | 移除所有已經(jīng)注冊的轉換器 |
deregister(final Class<?> clazz) | void | 移除指定類型的轉換器 |
lookup(final Class<?> clazz) | Converter | 查找指定類型的轉換器 |
lookup(final Class<?> sourceType, final Class<?> targetType) | Converter | 查找將指定類型轉換為另一種類型的轉換器 |
register(final Converter converter, final Class<?> clazz) | void | 注冊轉換器 |
primitiveToWrapper(final Class<T> type) | Class<T> | 基本類型轉換成包裝類 |
? ? ? ?ConvertUtils的使用乏盐。
public class ConvertUtilsTest {
@Test
public void test() {
try {
// 注冊一個Date轉換器佳窑,把字符串轉換為Date
ConvertUtils.register(new Converter() {
@Override
public <T> T convert(Class<T> type, Object value) {
try {
return (T) new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) value);
} catch (ParseException e) {
return null;
}
}
}, Date.class);
System.out.println(ConvertUtils.convert("2019-10-28 15:30:00", Date.class));
} catch (Exception e) {
e.printStackTrace();
}
}
}