分享一个基于反射机制实现的动态操纵 JavaBean 的工具类

源代码清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package org.fanlychie.util;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* 动态 Bean
*
* @author 范忠云(fanlychie)
*/
public class DynaBean {
// Bean 对象
private Object bean;
// Bean 类型
private Class<?> beanClass;
// Bean 对象的非静态属性对照表
private Map<String, Field> beanProps;
/**
* 实例化一个动态 Bean
*
* @param beanClass
* Bean 类型
*/
public DynaBean(Class<?> beanClass) {
this.beanClass = beanClass;
this.beanProps = getDeclaredFieldsMap(beanClass);
}
/**
* 实例化一个 Bean 对象
*/
public void newBeanInstance() {
try {
bean = beanClass.newInstance();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* 获取属性的类型
*
* @param name
* 属性名称
* @return 返回属性的类型
*/
public Class<?> getFieldType(String name) {
Field field = beanProps.get(name);
if (field == null) {
throw new RuntimeException(castExceptionMessage(name));
}
return field.getType();
}
/**
* 设置属性的值
*
* @param name
* 属性名称
* @param value
* 属性的值
*/
public void setFieldValue(String name, Object value) {
Field field = beanProps.get(name);
if (field == null) {
throw new RuntimeException(castExceptionMessage(name));
}
try {
field.set(bean, value);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* 获取属性的值
*
* @param bean
* 对象
* @param name
* 属性名称
* @return 返回对象中属性的值
*/
public Object getFieldValue(Object bean, String name) {
Field field = beanProps.get(name);
if (field == null) {
throw new RuntimeException(castExceptionMessage(name));
}
try {
return field.get(bean);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* 获取 Bean 的实例
*
* @return 返回 Bean 的实例
*/
public Object getBean() {
return bean;
}
/**
* 获取类声明的非静态属性表
*
* @param beanClass
* 类
* @return 返回类声明的非静态属性表
*/
private Map<String, Field> getDeclaredFieldsMap(Class<?> beanClass) {
// 获取类声明的属性集合
Field[] fields = beanClass.getDeclaredFields();
Map<String, Field> map = new HashMap<String, Field>();
// 迭代属性集合
for (Field field : fields) {
// 剔除静态属性
if ((field.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
// 强行设置成可访问
field.setAccessible(true);
map.put(field.getName(), field);
}
}
return map;
}
/**
* 异常信息
*
* @param name
* 属性名称
* @return 返回异常信息
*/
private String castExceptionMessage(String name) {
return String.format("Can not found property \"%s\" in class %s", name,
beanClass.getSimpleName());
}
}

测试对象清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Person {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + "]";
}
}

测试清单1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();
// 创建动态 Bean 实例
DynaBean dynaBean = new DynaBean(Person.class);
// 创建一个 Bean 的实例
dynaBean.newBeanInstance();
// 设置 Bean 属性的值
dynaBean.setFieldValue("name", "张三");
dynaBean.setFieldValue("sex", "男");
// 取出 Bean 对象
persons.add((Person) dynaBean.getBean());
// 创建一个 Bean 的实例
dynaBean.newBeanInstance();
// 设置 Bean 属性的值
dynaBean.setFieldValue("name", "李四");
dynaBean.setFieldValue("sex", "女");
// 取出 Bean 对象
persons.add((Person) dynaBean.getBean());
System.out.println(persons);
}

使用场景可参考 ReadableExcel - 基于 POI 和反射机制实现通用读取 Excel 表格数据

测试结果

1
[Person [name=张三, sex=男], Person [name=李四, sex=女]]

测试清单2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();
Person person1 = new Person();
person1.setName("张三");
person1.setSex("男");
persons.add(person1);
Person person2 = new Person();
person2.setName("李四");
person2.setSex("女");
persons.add(person2);
// 创建动态 Bean 实例
DynaBean dynaBean = new DynaBean(Person.class);
for (Person person : persons) {
System.out.println(String.format("[name=%s, sex=%s]",
// 获取 Bean 对象的 name 属性的值
dynaBean.getFieldValue(person, "name"),
// 获取 Bean 对象的 sex 属性的值
dynaBean.getFieldValue(person, "sex")));
}
}

使用场景可参考 WritableExcel - 基于 POI 和反射机制实现通用写出 Excel 文档文件

测试结果

1
2
3
[name=张三, sex=男]
[name=李四, sex=女]