基于反射,根据参数和类动态生成实例对象

这篇文章是基于我第一篇文章,mysql反向工程代码的dbHelper类的基础,对于我第一篇文章的部分解惑。

把这个看完基本能学会反射的简单使用了。

目前只支持基础数据类型,如果想支持更多的类型,自己在那一堆else if后面继续补充就行了

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
public class GenerateObject {
public static <T> List<T> parseManyObject(List<Map<String,Object>> list, Class<T> c) throws Exception {
List<T> result = new ArrayList<>();
for (Map<String, Object> map : list) {
T t = parseObject(map,c);
result.add(t);
}
return result;
}

//重载方法
public static <T> T parseObject(Map<String,Object> map, Class<T> c) throws Exception {
T o = c.newInstance();

//2.取c基因中的所有方法
Method[] methods = c.getDeclaredMethods();

//筛选出set方法即可
List setMethods = allSetMethods(methods);

//3.循环map所有的键值对,通过set方法注入到o对象中
Set<Map.Entry<String, Object>> set = map.entrySet();
Iterator<Map.Entry<String, Object>> iterator = set.iterator();
while (iterator.hasNext()){
Map.Entry<String, Object> entry = iterator.next();
String name = entry.getKey(); //属性名
Object value = entry.getValue(); //对应的值

//根据name 取setXxx方法;
Method m = findSetMethod(name,setMethods);

Class parameterTypeClass = m.getParameterTypes()[0];
String parameterTypeName = parameterTypeClass.getName();
if (parameterTypeName.equals("int") || parameterTypeName.equals("java.lang.Integer")){
m.invoke(o,Integer.parseInt(value.toString()));
} else if (parameterTypeName.equals("short") || parameterTypeName.equals("java.lang.Short")){
m.invoke(o,Short.parseShort(value.toString()));
}else if (parameterTypeName.equals("double") || parameterTypeName.equals("java.lang.Double")){
m.invoke(o,Double.parseDouble(value.toString()));
}else if (parameterTypeName.equals("float") || parameterTypeName.equals("java.lang.Float")){
m.invoke(o,Float.parseFloat(value.toString()));
}else if (parameterTypeName.equals("long") || parameterTypeName.equals("java.lang.Long")){
m.invoke(o,Integer.parseInt(value.toString()));
}else if (parameterTypeName.equals("byte") || parameterTypeName.equals("java.lang.Byte")){
m.invoke(o,Byte.parseByte(value.toString()));
}else if (parameterTypeName.equals("boolean") || parameterTypeName.equals("java.lang.Boolean")){
m.invoke(o,Boolean.parseBoolean(value.toString()));
}else {
m.invoke(o,value);
}
}
return o;
}




/**
* 根据输入动态生成对象
* @param values 对象中各种属性的值
* @param names 属性名(按values一一排序
* @param c 要生成的对象的反射对象(基因
* @return 生成好的对象
*/
public static Object parseObject(String[] values,String[] names,Class c) throws Exception {
//1.根据c生成对象
Object o = c.newInstance();

//2.取出c中所有的方法
Method[] methods = c.getDeclaredMethods(); //所有的get(),所有的set(),toString()...
//筛选出set方法即可
List setMethods = allSetMethods(methods);

//3.循环values所有的值,通过set方法注入到o对象
for (int i = 0; i < values.length; i++) {
//System.out.println("1");
String value = values[i]; //取值
String name = names[i]; //取对应的属性名

//根据name 取setXxx方法
Method setMethod = findSetMethod(name,setMethods);

//要针对不同的参数类型进行强转
//激活这个对象
//解决方法:获取setMethod中参数的类型,判断类型是什么
Class parameterTypeClass = setMethod.getParameterTypes()[0];
String parameterTypeName = parameterTypeClass.getName();
if (parameterTypeName.equals("int") || parameterTypeName.equals("java.lang.Integer")){
setMethod.invoke(o,Integer.parseInt(value));
} else if (parameterTypeName.equals("short") || parameterTypeName.equals("java.lang.Short")){
setMethod.invoke(o,Short.parseShort(value));
}else if (parameterTypeName.equals("double") || parameterTypeName.equals("java.lang.Double")){
setMethod.invoke(o,Double.parseDouble(value));
}else if (parameterTypeName.equals("float") || parameterTypeName.equals("java.lang.Float")){
setMethod.invoke(o,Float.parseFloat(value));
}else if (parameterTypeName.equals("long") || parameterTypeName.equals("java.lang.Long")){
setMethod.invoke(o,Integer.parseInt(value));
}else if (parameterTypeName.equals("byte") || parameterTypeName.equals("java.lang.Byte")){
setMethod.invoke(o,Byte.parseByte(value));
}else if (parameterTypeName.equals("boolean") || parameterTypeName.equals("java.lang.Boolean")){
setMethod.invoke(o,Boolean.parseBoolean(value));
}else {
setMethod.invoke(o,value);
}
}

return o;
}

/**
* 在所有待查找的setMethods中查出名字叫 setXxx
* @param name 属性名
* @param setMethods 待查找的方法
* @return
*/
private static Method findSetMethod(String name, List setMethods) {
for (int i = 0; i < setMethods.size(); i++) {
Method m = (Method) setMethods.get(i);
String methodname = "set" + name.substring(0,1).toUpperCase() + name.substring(1);
if (m.getName().equals(methodname)){
return m;
}
}
return null;
}


/**
* 从methods数组中去除所有的set方法
*
* @param methods
* @return
*/
private static List allSetMethods(Method[] methods){
List setMethods = new ArrayList(); //存set方法
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().startsWith("set")){
setMethods.add(methods[i]);
}
}
return setMethods;
}
}

测试代码

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
public static void main(String[] args) throws Exception {
Map<String,Object> student1 = new Hashtable<>();
student1.put("id",1);
student1.put("name","张三");
student1.put("weight",60);

Student s = GenerateObject.parseObject(student1, Student.class);
System.out.println(s);


Map<String,Object> student2 = new Hashtable<>();
student1.put("id",2);
student1.put("name","李四");
student1.put("weight",60);

Map<String,Object> student3 = new Hashtable<>();
student1.put("id",3);
student1.put("name","王五");
student1.put("weight",60);

List<Map<String,Object>> list = new ArrayList<>();
list.add(student1);
list.add(student2);
list.add(student3);

List<Student> ss = GenerateObject.parseManyObject(list,Student.class);
for (Student stu : ss) {
System.out.println(stu);
}
/*Student s= new Student();
System.out.println(s.getClass());
System.out.println(s.getClass().getClass());
System.out.println(s.getClass().getClass().getClass());
System.out.println(s.getClass().getClass().getClass().getClass());*/
}