反射機制是在運行狀態中,可以知道任何一個類的屬性和方法,并且調用類的屬性和方法;
反射機制能夠做什么
1、判斷運行對象的所屬類
2、構造任意一個類的對象
3、獲取任意一個類的屬性和方法
4、調用任意屬性和方法
5、生成動態代理
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
package coral.base.util; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import wfc.service.database.RecordSet; public class ReflectUtils { /** * 將一個map集合封裝成為bean對象 * * @param param * @param clazz * @return */ public static <T> T MapToBean(Map<String, Object> param, Class<?> clazz) { Object value = null ; Class[] paramTypes = new Class[ 1 ]; Object obj = null ; try { obj = clazz.newInstance(); // 獲取類的屬性 Field[] declaredFields = clazz.getDeclaredFields(); // 獲取父類或接口的公有屬性 Field[] superFields = clazz.getSuperclass().getFields(); List<Field[]> list = new ArrayList<Field[]>(); if (declaredFields != null ) { list.add(declaredFields); } if (superFields != null ) { list.add(superFields); } for (Field[] fields : list) { for (Field field : fields) { String fieldName = field.getName(); // 獲取屬性對應的值? value = param.get(fieldName); // 把值設置進入對象屬性中 這里可能是有屬性但是沒有相應的set方法,所以要做異常處理 try { PropertyDescriptor pd = new PropertyDescriptor( fieldName, clazz); Method method = pd.getWriteMethod(); method.invoke(obj, new Object[] { value }); } catch (Exception e1) { } } } } catch (Exception e1) { } return (T) obj; } /** * 獲取類的所有屬性,包括父類和接口 * @param clazz * @return */ public static List<Field[]> getBeanFields(Class<?> clazz) { List<Field[]> list = new ArrayList<Field[]>(); Field[] declaredFields = clazz.getDeclaredFields(); Field[] superFields = clazz.getSuperclass().getFields(); if (declaredFields != null ) { list.add(declaredFields); } if (superFields != null ) { list.add(superFields); } return list; } /** * 從結果集中獲取出值 * @param fieldName * @param rs * @return */ public static Object getFieldValue(String fieldName, ResultSet rs) { Object value = null ; try { //捕獲值不存在的異常 value = rs.getObject(fieldName); return value; } catch (SQLException e) { //oracle數據庫的列都是大寫,所以才查找一次 fieldName = fieldName.toLowerCase(); try { value = rs.getObject(fieldName); return value; } catch (SQLException e1) { //結果集中沒有對應的值,返回為空 return null ; } } } /** * 方法重載, * @param fieldName * @param rs 這個是封裝過的結果集 * @return */ public static Object getFieldValue(String fieldName, RecordSet rs) { Object value = null ; value = rs.getObject(fieldName); return value; } /** * 方法重載 * @param rs 封裝過的結果集 * @param clazz * @return */ public static <T> T RSToBean(RecordSet rs, Class<?> clazz) { Object obj = null ; List<Field[]> list = getBeanFields(clazz); try { obj = clazz.newInstance(); for (Field[] fields : list) { for (Field field : fields) { String fieldName = field.getName(); // String fieldName = field.getName();? Object value = getFieldValue(fieldName, rs); try { PropertyDescriptor pd = new PropertyDescriptor( fieldName, clazz); Method method = pd.getWriteMethod(); method.invoke(obj, new Object[] { value }); } catch (Exception e1) { } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return (T) obj; } /** * 把結果集封裝成為bean對象 * @param rs * @param clazz * @return */ public static <T> T RSToBean(ResultSet rs, Class<?> clazz) { Object obj = null ; List<Field[]> list = getBeanFields(clazz); try { while (rs.next()) { obj = clazz.newInstance(); for (Field[] fields : list) { for (Field field : fields) { String fieldName = field.getName(); // String fieldName = field.getName();? Object value = getFieldValue(fieldName, rs); PropertyDescriptor pd = new PropertyDescriptor( fieldName, clazz); Method method = pd.getWriteMethod(); method.invoke(obj, new Object[] { value }); } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return (T) obj; } /** * 把結果集封裝成為List * * @param rs * @param clazz * @return */ public static <T> List<T> RsToList(ResultSet rs, Class<?> clazz) { ArrayList<T> objList = new ArrayList<T>(); // 獲取所有的屬性 List<Field[]> list = getBeanFields(clazz); try { while (rs.next()) { // 定義臨時變量 Object tempObeject = clazz.newInstance(); // 添加到屬性中 for (Field[] fields : list) { for (Field field : fields) { String fieldName = field.getName(); // 獲取屬性值? Object value = getFieldValue(fieldName, rs); PropertyDescriptor pd = new PropertyDescriptor( fieldName, clazz); Method method = pd.getWriteMethod(); method.invoke(tempObeject, new Object[] { value }); } } objList.add((T) tempObeject); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return objList; } } |
補充知識:java反射自動封裝值到實體類
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
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
|
package com.util; import com.entity.Student; import javax.servlet.ServletRequest; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Enumeration; /** * Created by wq on 2017/8/30. */ public class BeanOperateTools { /* 利用反射進行所以請求參數的設置,要求參數名與屬性名一致 */ /** * * @param obj * @param req * @param datePatern 將字符串變為日期時間格式化的字符串 * @throws Exception */ public static void setValue(Object obj, ServletRequest req,String datePatern) throws Exception { //設置屬性的內容 { System.out.println( "進了setValue方法....." ); //取得class對象 Class<?> cls = obj.getClass(); //取得輸入的全部參數名稱 Enumeration<String> enu = req.getParameterNames(); //循環輸入的全部參數名稱 while (enu.hasMoreElements()) { String paramName = enu.nextElement(); //取得參數名稱 String paramValue = req.getParameter(paramName); //取得屬性的類型是為了取得參數的類型,以確定method方法和是否轉型 Field field = cls.getDeclaredField(paramName); //取得指定名稱的屬性 (實體類里面 //取得指定的操作方法,以滿足反射調用 Method method = cls.getMethod( "set" +StringTools.initcap(paramName),field.getType()); //根據類型進行數據的轉換,同時調用setter設置數據 //取得類型 String fieldType=field.getType().getSimpleName(); if ( "string" .equalsIgnoreCase(fieldType)) { method.invoke(obj,paramValue); } else if ( "integer" .equalsIgnoreCase(fieldType)|| "int" .equalsIgnoreCase(fieldType)){ method.invoke(obj,Integer.parseInt(paramValue)); } else if ( "double" .equalsIgnoreCase(fieldType)){ method.invoke(obj,Double.parseDouble(paramValue)); } else if ( "date" .equalsIgnoreCase(fieldType)){ method.invoke(obj, new SimpleDateFormat(datePatern).parse(paramValue)); } } } } } |
2.servlet中調用此方法
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
|
package com.servlet; import com.entity.Student; import com.sun.xml.internal.bind.v2.runtime.reflect.opt.FieldAccessor_Double; import com.util.BeanOperateTools; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Enumeration; /** * Created by wq on 2017/8/22. */ @WebServlet (name = "studentServlet" , urlPatterns = { "/StudentServlet" }) public class StudentServlet extends HttpServlet { //private Student stu = new Student(); private Student student= new Student(); public Student getStudent() { return student; } public void setStudent(Student student) { this .student = student; } -------此處模仿依賴注入 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding( "UTF-8" ); try { BeanOperateTools.setValue( this .getStudent(),req, "yyyy-MM-dd" ); } catch (Exception e) { e.printStackTrace(); } req.setAttribute( "student" , this .student); req.getRequestDispatcher( "student_insert_do.jsp" ).forward(req,resp); // Class<?> cls= this.stu.getClass(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this .doGet(req, resp); } public String initcap(String str) { //首字母大寫 return str.substring( 0 , 1 ).toUpperCase().concat(str.substring( 1 ).toLowerCase()); } } |
3.新增學生的jsp頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<%-- Created by IntelliJ IDEA. User: wq Date: 2017/8/21 Time: 23:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> < html > < head > < title >Title</ title > </ head > < body > < form action = "StudentServlet" method = "post" > 姓名:< input type = "text" name = "name" >< br > 年齡:< input type = "text" name = "age" >< br > 成績:< input type = "text" name = "score" >< br > < input type = "submit" value = "輸入" > < input type = "reset" value = "重置" > </ form > </ body > </ html > |
4。展示學生的信息的頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<%-- Created by IntelliJ IDEA. User: wq Date: 2017/8/21 Time: 23:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> < html > < head > < title >Title</ title > </ head > < body > < h1 >姓名:${student.name}</ h1 > < h1 >年齡:${student.age}</ h1 > < h1 >成績:${student.score}</ h1 > </ body > </ html > |
以上這篇使用java反射將結果集封裝成為對象和對象集合操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/alleged/article/details/72726220