JavaSE(十六)——反射
文章目錄
- 1. 概述
- 2. Class類
- 3. 獲取Class對象的三種方式
- 4. 獲取類的結構信息
- 5. 創建類的對象
- 6. 調用指定的方法
- 7. 反射操作泛型
1. 概述
- Java可稱為“準動態語言”,有一定的動態性,可以利用反射機制獲得類似動態語言(即在運行時代碼可依據某些條件改變自身結構)的特性。
- 反射機制:在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
- 要想解剖一個類,必須先要獲取到該類的字節碼文件對象。
- 反射相關的主要API
java.lang.Class: 代表一個類
java.lang.reflect.Method : 代表類的方法
java.lang.reflect.Field : 代表類的成員變量
java.lang.reflect.Constructor : 代表類的構造器
2. Class類
-
在Object類中定義了方法:public final Class getClass(),此方法將被所有子類繼承。
-
(1)Class 本身也是一個類
(2)Class 對象只能由系統建立對象
(3)一個加載的類在 JVM 中只會有一個Class實例
(4)一個Class對象對應的是一個加載到JVM中的一個.class文件
(5)每個類的實例都會記得自己是由哪個 Class 實例所生成
(6)通過Class可以完整地得到一個類中的所有被加載的結構
(7) Class類是Reflection的根源,針對任何你想動態加載、運行的類,唯有先獲得相應的 Class對象 -
Class類的常用方法
-
Java內存分析
3. 獲取Class對象的三種方式
-
① Object類的getClass()方法
② 靜態屬性class
③ Class類中靜態方法forName() -
案例:
-
運行結果:
4. 獲取類的結構信息
- 對象就包含了完整的類的結構信息。可以通過這個對象看到類的結構。這個對象就像一面鏡子,透過這個鏡子看到類的結構,如類名、屬性(字段)、方法、構造器等。
- 代碼演示:
5. 創建類的對象
-
調用forName()返回的是Class,后需要調用newInstance()實例化
-
方式一: 調用Class對象的newInstance()方法,條件:①類必須有一個無參數的構造器, ②類的構造器的訪問權限需要足。
-
方式二:1)通過Class類的getDeclaredConstructor(Class … parameterTypes)取得本類的指定形參類型的構造器 2)向構造器的形參中傳遞一個對象數組進去,里面包含了構造器中所需的各個參數。 3)通過Constructor實例化對象
-
代碼:
-
運行結果:
6. 調用指定的方法
-
通過反射,調用類中的方法,通過Method類完成。
① 通過Class類的getMethod(String name,Class…parameterTypes)方法取得 一個Method對象,并設置此方法操作時所需要的參數類型。
② 之后使用Object invoke(Object obj, Object[] args)進行調用,并向方法中傳 遞要設置的obj對象的參數信息。 -
代碼:
-
若原方法聲明為private,則需要在調用invoke()方法之前,顯示調用方法對象的setAccessible(true)方法,將可訪問private的方法。
-
代碼:
7. 反射操作泛型
- Java采用泛型擦除的機制來引入泛型,Java中的泛型僅僅是給編譯器javac使用的,確保數據的安全性和免去強制類型轉換問題,但是一旦編譯完成,所有和泛型有關的類型全部擦除。
- 為了通過反射操作這些類型 , Java新增了 ParameterizedType , GenericArrayType , TypeVariable 和 WildcardType 幾種類型來代表不能被歸一到Class類中的類型但是又和原始類型齊名的類型。
- ParameterizedType : 表示一種參數化類型,比如Collection GenericArrayType : 表示一種元素類型是參數化類型或者類型變量的數組類型
TypeVariable : 是各種類型變量的公共父接口
WildcardType : 代表一種通配符類型表達式
總結
以上是生活随笔為你收集整理的JavaSE(十六)——反射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaSE(十五)——注解
- 下一篇: JavaSE(十七)——IO流之字节流