JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意一個方法。這種動態獲取的以及動態調用對象的方法的功能稱為java語言的反射機制。 簡單來說, 就可以把.class文件比做動物的屍體, 而反射技術就是對屍體的一種解剖.通過反射技術, ...
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意一個方法。這種動態獲取的以及動態調用對象的方法的功能稱為java語言的反射機制。
簡單來說, 就可以把.class文件比做動物的屍體, 而反射技術就是對屍體的一種解剖.通過反射技術, 我們可以拿到該位元組碼文件中所有的東西, 例如成員變數, 成員方法, 構造方法, 而且還包括私有。
位元組碼文件的三種獲取方式:
- 對象名.getCalss(); // 次方法來自於Object對象已經存在的情況下,可以使用這種方式
- 類名.class //類名.class這是一個靜態的屬性,只要知道類名,就可以獲取
- Class.forName(“com.lfh.Student”); // 通過Class類中的靜態方法,指定字元串,該字元串是類的全類名(包名+類名)
獲取構造方法:
//獲取位元組碼對象
Class clazz = Class.forName("myReflectDemo.student1");
//調用無參數構造方法
Constructor cs =clazz.getConstructor();
//System.out.println(cs);
//調用有參數構造方法
Constructor css = clazz.getConstructor(String.class,int.class);
Object obj =css.newInstance("zhangsan",15);
System.out.println(css);
System.out.println(obj);
System.out.println("---------------");
//可以直接使用clazz.newInstance(),直接調用!!!
Object obj1 = clazz.newInstance();
System.out.println(obj1);
獲取成員變數:
Class clazz = Class.forName("myReflectDemo.student1");
Object obj = clazz.newInstance();
// 訪問所有的成員變數 返回數組
Field[] f = clazz.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
Field field = f[i];
System.out.println(field);
}
// 返回指定的私有成員變數
Field name = clazz.getDeclaredField("name");
Field age = clazz.getDeclaredField("age");
age.set(obj, 18);
System.out.println(age.get(obj));
// 私有成員變數必須設置開關 不然無法訪問和修改!!!(讓jvm不檢查許可權)
name.setAccessible(true);
// 傳進來的是obj [ clazz.newInstance() ] 不是name
name.set(obj, "lisi");
System.out.println(name.get(obj));
獲取成員方法:
Class clazz = Class.forName("myReflectDemo.student1");
Object obj = clazz.newInstance();
/*返回所有方法
* Method[] md =clazz.getDeclaredMethods();
for (int i = 0; i < md.length; i++) {
Method method = md[i];
System.out.println(method);
}*/
//獲取無參數無返回值的方法
Method m = clazz.getDeclaredMethod("method");
m.invoke(obj);
//獲取有參數無返回值的方法
Method m2 =clazz.getDeclaredMethod("method",String.class);
m2.invoke(obj, "信息");
//獲取無參數有返回值的方法
Method m3 =clazz.getDeclaredMethod("getName");
System.out.println(m3.invoke(obj));