国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - Java反射技術詳解及實例解析

Java反射技術詳解及實例解析

2020-07-14 18:00黃林晴 JAVA教程

這篇文章主要介紹了Java反射技術詳解及實例解析,反射可以說是Java中最強大的技術了,它可以做的事情太多太多,很多優秀的開源框架都是通過反射完成的。如果對JAVA感興趣來可以學習一下

前言

  相信很多人都知道反射可以說是Java中最強大的技術了,它可以做的事情太多太多,很多優秀的開源框架都是通過反射完成的,比如最初的很多注解框架,后來因為java反射影響性能,所以被運行時注解APT替代了,java反射有個開源框架jOOR相信很多人都用過,不過我們還是要學習反射的基礎語法,這樣才能自己寫出優秀的框架,當然這里所講的反射技術,是學習Android插件化技術、Hook技術等必不可少的!

一、基本反射技術

      1.1 根據一個字符串得到一個類

        getClass方法

?
1
2
3
String name = "Huanglinqing";
Class c1 = name.getClass();
System.out.println(c1.getName());

     打印結果如下:

Java反射技術詳解及實例解析

    Class.forName

    比如我們獲取java.lang.String的類名 

?
1
2
3
4
5
6
7
String name = "java.lang.String";
Class c1 = null;
try {
 c1 = Class.forName(name);
 System.out.println(c1.getName());
} catch (ClassNotFoundException e) {
}

這里也通過捕獲異常,因為我們傳的這個字符串可能不合法,字符串合法命名是類的命名空間和類的名稱組成

    打印結果如下:

Java反射技術詳解及實例解析

我們還可以通過c1.getSuperclass()獲取到他的父類

   Type屬性

    基本類型都有type屬性,可以得到這個基本類型的類型,比如:

?
1
2
3
4
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;

停停停!這些東西有啥子用,如此雞肋! 別急,一切都是為后續做準備。

二、獲取類的成員

         當類中方法定義為私有的時候我們能調用?不能!當變量是私有的時候我們能獲取嗎?不能!但是反射可以,比如源碼中有你需要用到的方法,但是那個方法是私有的,這個時候你就可以通過反射去執行這個私有方法,并且獲取私有變量。

       獲取類的構造函數

       為了便于測試,我們定義一個Test類,Test類如下:(省略get和set方法)

       Test類中我們定義是三個私有變量,生成兩個公有的含參構造方法和一個私有的含參構造方法以及一個公有的無參構造方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Test {
 
 private int age;
 private String name;
 private int testint;
 
 public Test(int age) {
 this.age = age;
 }
 
 public Test(int age, String name) {
 this.age = age;
 this.name = name;
 }
 
 private Test(String name) {
 this.name = name;
 }
 
 public Test() {
 }

      下面我們通過反射獲取這些構造方法

       獲取類的所有構造方法

?
1
2
3
4
Test test = new Test();
Class c4 = test.getClass();
Constructor[] constructors ;
constructors = c4.getDeclaredConstructors();

      通過getDeclaredConstructors可以返回類的所有構造方法,返回的是一個數組因為構造方法可能不止一個,通過getModifiers可以得到構造方法的類型,getParameterTypes可以得到構造方法的所有參數,返回的是一個Class數組,所以我們如果想獲取所有構造方法以及每個構造方法的參數類型,可以有如下代碼:

?
1
2
3
4
5
6
7
8
for (int i = 0; i < constructors.length; i++) {
System.out.print(Modifier.toString(constructors[i].getModifiers()) + "參數:");
Class[] parametertypes = constructors[i].getParameterTypes();
for (int j = 0; j < parametertypes.length; j++) {
 System.out.print(parametertypes[j].getName() + " ");
}
System.out.println("");
}

    運行結果如下所示:

Java反射技術詳解及實例解析

    這樣我們就得到了類中所有構造方法和構造方法中的參數,那么我們如何獲取特定的構造方法呢?

    獲取類中特定的構造方法

    我們可以通過getConstructors方法獲取類中 所有的public類型的構造方法,代碼和上面一樣就不演示了。

    我們可以通過getDeclaredConstructor()方法傳參獲取特定參數類型的構造方法,這里注意是getDeclaredConstructor()不是  getDeclaredConstructors() ,所以返回的是一個Class對象而不是一個Class數組。

    獲取無參構造方法直接不傳參數,如下所示:

?
1
2
3
4
5
6
try {
 constructors = c4.getDeclaredConstructor();
 System.out.print(Modifier.toString(constructors.getModifiers()) + );
} catch (NoSuchMethodException e) {
 e.printStackTrace();
}

    這里要進行異常捕獲,因為可能不存在對應的構造方法,打印結果如下:  

Java反射技術詳解及實例解析

 如果我們想獲取有兩個參數分別為int和String類型的構造方法,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
Class[] p = {int.class,String.class};
try {
constructors = c4.getDeclaredConstructor(p);
System.out.print(Modifier.toString(constructors.getModifiers()) + "參數:");
Class[] parametertypes = constructors.getParameterTypes();
for (int j = 0; j < parametertypes.length; j++) {
 System.out.print(parametertypes[j].getName() + " ");
 }
} catch (NoSuchMethodException e) {
 e.printStackTrace();
}

  這里我們同樣打印出構造方法的參數:

Java反射技術詳解及實例解析

  調用構造方法

   從這里開始慢慢到了關鍵的一步,得到類的實例,我們主要借助于newInstance方法,為了方便演示我們將測試類的兩個構造方法打印出來. 

?
1
2
3
4
5
6
7
8
9
10
11
12
public Test(int age, String name) {
this.age = age;
this.name = name;
System.out.println("hello" + name + "i am" + age);
}
 
 
private Test(String name) {
this.name = name;
System.out.println("My Name is" +
 name);
}

   我們先來調用public的方法,如下所示:

?
1
2
3
Class[] p = {int.class,String.class};
constructors = c4.getDeclaredConstructor(p);
constructors.newInstance(24,"HuangLinqing");

 運行打印結果如下:

Java反射技術詳解及實例解析

 那么調用私有構造方法呢,和上面一樣,只是我們要設置constructors.setAccessible(true);代碼如下:

?
1
2
3
4
Class[] p = {String.class};
constructors = c4.getDeclaredConstructor(p);
constructors.setAccessible(true);
constructors.newInstance("HuangLinqing");

打印結果如下:

Java反射技術詳解及實例解析

調用類的私有方法

  如何調用類中的私有方法呢,我們先在測試類中編寫一個測試的私有方法 如下:

?
1
2
3
private void welcome(String tips){
System.out.println(tips);
}

  我們知道如果我們要正常的調用類的方法都是通過類.方法調用,所以我們調用私有方法也需要得到類的實例,而我們上面newInstace已經得到了類的實例,這樣就好辦了。

?
1
2
3
Class[] p4 = {String.class};
 Method method = c4.getDeclaredMethod("welcome",p4);
 method.setAccessible(true);

   我們首先通過 getDeclaredMethod方法獲取到這個私有方法,第一個參數是方法名,第二個參數是參數類型

   然后通過invoke方法執行,invoke需要兩個參數一個是類的實例,一個是方法參數。    

?
1
2
3
4
5
Class[] p4 = {String.class};
 Method method = c4.getDeclaredMethod("welcome",p4);
 method.setAccessible(true);
 Object arg1s[] = {"歡迎關注代碼男人技術公眾號"};
 method.invoke(test,arg1s);

     test類的實例當不能new 獲取的時候我們也可以通過反射獲取,就是上面的newInstance方法。打印結果如下:

Java反射技術詳解及實例解析

 獲取類的私有字段并修改值

  看到這里你可能會說,有了set方法,什么私有不私有,test.set不就可以了,但是這里要注意我們是沒有辦法得到這個類的實例的,要不然都可以得到實例就沒有反射一說了。我們在通過反射得到類的實例之后先獲取字段:

?
1
2
3
Field field = c4.getDeclaredField("name");
field.setAccessible(true);
field.set(o,"代碼男人");

   o是我們上面通過反射構造方法獲取的實例,  打印field.get(o).toString()的值如下:

Java反射技術詳解及實例解析

   不過要注意的是我們修改了name的值只對當前的實例對象有效。

   Java的基本反射語法就是這樣了,歡迎加入技術群一起探討!

  最后反射封裝類如下:

?
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
package jnidemo.hlq.com.hookdemo;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
 
/**
 * @author Huanglinqing
 * @date 2019/4/28
 */
 
public class Reflex {
 
 /**
 * 獲取無參構造函數
 * @param className
 * @return
 */
 public static Object createObject(String className) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 try {
  Class r = Class.forName(className);
  return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 獲取無參構造方法
 * @param clazz
 * @return
 */
 public static Object createObject(Class clazz) {
 Class[] pareTyple = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return createObject(clazz, pareTyple, pareVaules);
 }
 
 /**
 * 獲取一個參數的構造函數 已知className
 *
 * @param className
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object createObject(String className, Class pareTyple, Object pareVaule) {
 
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 try {
  Class r = Class.forName(className);
  return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取單個參數的構造方法 已知類
 *
 * @param clazz
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object createObject(Class clazz, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return createObject(clazz, pareTyples, pareVaules);
 }
 
 /**
 * 獲取多個參數的構造方法 已知className
 * @param className
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
 try {
  Class r = Class.forName(className);
  return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取構造方法
 *
 * @param clazz
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object createObject(Class clazz, Class[] pareTyples, Object[] pareVaules) {
 try {
  Constructor ctor = clazz.getDeclaredConstructor(pareTyples);
  ctor.setAccessible(true);
  return ctor.newInstance(pareVaules);
 } catch (Exception e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取多個參數的方法
 * @param obj
 * @param methodName
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
 if (obj == null) {
  return null;
 }
 
 try {
  //調用一個private方法 //在指定類中獲取指定的方法
  Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples);
  method.setAccessible(true);
  return method.invoke(obj, pareVaules);
 
 } catch (Exception e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 獲取一個參數的方法
 * @param obj
 * @param methodName
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = {pareTyple};
 Object[] pareVaules = {pareVaule};
 
 return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules);
 }
 
 /**
 * 獲取無參方法
 * @param obj
 * @param methodName
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules);
 }
 
 
 /**
 * 無參靜態方法
 * @param className
 * @param method_name
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeStaticMethod(className, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 獲取一個參數的靜態方法
 * @param className
 * @param method_name
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return invokeStaticMethod(className, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 獲取多個參數的靜態方法
 * @param className
 * @param method_name
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
 try {
  Class obj_class = Class.forName(className);
  return invokeStaticMethod(obj_class, method_name, pareTyples, pareVaules);
 } catch (Exception e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 無參靜態方法
 * @param method_name
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeStaticMethod(clazz, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 一個參數靜態方法
 * @param clazz
 * @param method_name
 * @param classType
 * @param pareVaule
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name, Class classType, Object pareVaule) {
 Class[] classTypes = new Class[]{classType};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return invokeStaticMethod(clazz, method_name, classTypes, pareVaules);
 }
 
 /**
 * 多個參數的靜態方法
 * @param clazz
 * @param method_name
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name, Class[] pareTyples, Object[] pareVaules) {
 try {
  Method method = clazz.getDeclaredMethod(method_name, pareTyples);
  method.setAccessible(true);
  return method.invoke(null, pareVaules);
 } catch (Exception e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 
 public static Object getFieldObject(String className, Object obj, String filedName) {
 try {
  Class obj_class = Class.forName(className);
  return getFieldObject(obj_class, obj, filedName);
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }
 return null;
 }
 
 public static Object getFieldObject(Class clazz, Object obj, String filedName) {
 try {
  Field field = clazz.getDeclaredField(filedName);
  field.setAccessible(true);
  return field.get(obj);
 } catch (Exception e) {
  e.printStackTrace();
 }
 
 return null;
 }
 
 
 public static void setFieldObject(Class clazz, Object obj, String filedName, Object filedVaule) {
 try {
  Field field = clazz.getDeclaredField(filedName);
  field.setAccessible(true);
  field.set(obj, filedVaule);
 } catch (Exception e) {
  e.printStackTrace();
 }
 }
 
 public static void setFieldObject(String className, Object obj, String filedName, Object filedVaule) {
 try {
  Class obj_class = Class.forName(className);
  setFieldObject(obj_class, obj, filedName, filedVaule);
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }
 }
 
 
 public static Object getStaticFieldObject(String className, String filedName) {
 return getFieldObject(className, null, filedName);
 }
 
 public static Object getStaticFieldObject(Class clazz, String filedName) {
 return getFieldObject(clazz, null, filedName);
 }
 
 public static void setStaticFieldObject(String classname, String filedName, Object filedVaule) {
 setFieldObject(classname, null, filedName, filedVaule);
 }
 
 public static void setStaticFieldObject(Class clazz, String filedName, Object filedVaule) {
 setFieldObject(clazz, null, filedName, filedVaule);
 }
}

到此這篇關于Java反射技術詳解及實例解析的文章就介紹到這了,更多相關Java反射技術示例詳解內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/huangliniqng/article/details/88554510

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲视频在线观看网址 | 久久久久久亚洲精品 | 一区二区免费在线视频 | av国产精品 | 来个一级毛片 | 久久综合2019| 国产一级特黄 | 日本狠狠干 | 色噜 | 成人超碰在线 | 日韩在线一区二区三区 | 国产乱码一区二区三区在线观看 | 天天操人人干 | 成人精品影院 | 日韩中文视频 | 正在播放国产精品 | 激情久久综合网 | 日本动漫一区 | 亚洲精品在线看 | 午夜小电影| 欲色视频 | 亚洲国产精品久久 | 中文字幕av在线 | 欧美中文字幕在线 | 久久久久久久国产 | 亚洲国产中文字幕 | 日韩在线不卡 | 国产亚洲一区二区三区在线观看 | 国产一级片 | 精久久 | 欧美一区二区三区在线看 | 国产精品成人在线视频 | 在线观看黄色 | 久草电影网 | 亚洲国产精品一区二区第一页 | 中文字幕视频在线免费 | 激情综合欧美 | 成人午夜视频在线播放 | 精品黄色一级片 | 国产高清精品在线 | 一区二区在线视频 |