一、反射概述
(一)反射就是在運行時通過代碼操作類。
想要操作類,就必須先獲得該類的字節碼對象.Class。通過Class提供的方法對類進行進一步的解剖,從而實現各種操作。
(二)類各個組成的專業描述
Class類
Constructor 構造
Method 方法
Field 字段
instance 實例
invoke 執行
(三)JavaBean用于反射操作
Javabean規范
1.提供私有字段
2.提供get或set方法,可以使用快捷鍵生成
3.提供無參構造方法
4.必須要實現序列化接口 Java.io.Serializable
二、java 提供三種方式來獲得Class,
不同的應用場景,需要不同的方式獲得Class對象
(一)方式:
1.通過字符串(全限定類名)獲得
格式:Class clazz = Class.forName("字符串");
全限定類名:包名+類名
2.通過Java類型獲得
格式:Class clazz = 類型.class;
3.通過實例對象獲得
格式:Class clazz ?= obj.getClass();
(二)應用場景:
方式1:之后開發中,從配置文件中,獲得“全限定類名”,并通過反射進行所有操作
方式2:確定構造方法、普通方法形參列表時,需要通過類型獲得
方式3:方法內部通過變量名獲得
三、反射獲得實例化對象
(一)通過無參構造方法獲得實例對象
1.獲得Class對象
Class clazz = Class.forName("全限定類名");
2.通過clazz獲得無參構造,相當于:Bean()
//getConstructor()獲得指定形參列表的構造方法
Constructor cons = clazz.getConstructor();//返回無參構造函數
3.通過構造對象獲得實例化對象,相當于:new Bean()
//newInstance()創建指定實參的實例對象
Object obj = cons.newInstance();
(二)有參構造
1.獲得Class對象
Class clazz = Class.forName("reflect_bean.Bean");
?2.通過clazz獲得無參構造,相當于:Bean()
//getConstructor()獲得指定形參列表的構造方法
Constructor cons = clazz.getConstructor(String.class);//返回無參構造函數
? 3.通過構造對象獲得實例化對象,相當于:new Bean()
//newInstance()創建指定實參的實例對象
Object obj = cons.newInstance("b002");
System.out.println(obj);
(三)無參構造的簡寫方式
1.獲得Class對象
Class clazz = Class.forName("reflect_bean.Bean");
/2.通過clazz直接創建對象
Object object = clazz.newInstance();
(四)私有反射(暴力反射)
1.獲得Class對象
Class clazz = Class.forName("reflect_bean.Bean");
? 2.獲得指定形參私有構造
// clazz.getConstructor(...):獲得指定對象指定的public構造方法
// clazz.getDeclaredConstructor(...):獲得指定對象指定的任意構造方法,包含私有構造
Constructor constructor = clazz.getDeclaredConstructor(String.class,String.class);
3.通知JVM,運行實例私有構造(默認不允許)
constructor.setAccessible(true);
? 4.創建實例化,并設置實際參數
Object object = constructor.newInstance("b001","名稱");
System.out.println(object);
三、反射普通方法
(一)public方法
1.獲得實例
Class clazz = Class.forName("reflect_bean.Bean");
? ? ? ? Object object = clazz.newInstance();
// 2.通過setId方法,設置數據
// 2.1獲得方法,需要明確形參列表,setId
Method method = clazz.getMethod("setId", String.class);
// 2.2執行方法,bean。setId(...)
// ? 確定實例對象,并執行正確方法,具體實際參數
? ? ? ? method.invoke(object,"b002");
// 3.通過getId方法,獲得數據
Method getMethod = clazz.getMethod("getId");
String s = (String) getMethod.invoke(object);
System.out.println(s);
(二)private方法
// 1.獲得實例
Class clazz = Class.forName("reflect_bean.Bean");
? ? ? ? Object object = clazz.newInstance();
// 2.通過setId方法,設置數據
// 2.1獲得方法,需要明確形參列表,setId
//? ? ? ? clazz.getMethod(name,...):只能獲得public方法
//? ? ? ? clazz.getDeclaredMethod(name,...):獲得已聲明的所有方法
? ? ? ? Method method = clazz.getDeclaredMethod("setId", String.class);
//? ? ? 2.2強制設置運行訪問私有訪問(暴力)
? ? ? ? method.setAccessible(true);
// 2.3執行方法,bean。setId(...)
// ? 確定實例對象,并執行正確方法,具體實際參數
? ? ? ? method.invoke(object,"b002");
// 3.通過getId方法,獲得數據
Method getMethod = clazz.getMethod("getId");
String s = (String) getMethod.invoke(object);
System.out.println(s);