反射

一、反射概述

(一)反射就是在運行時通過代碼操作類。

想要操作類,就必須先獲得該類的字節碼對象.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);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容