JAVA安全基礎之反射
JAVA安全基礎之反射
在JAVA安全中,反射是一個經常使用的技術,所以熟悉使用反射是非常必要的。下面就簡單的講下JAVA的反射的用法
什麼是反射
每個類都有對應的Class類物件,該Class類物件包含該類的屬性、方法等資訊,這個Class類物件就是這個類的反射。
就像鏡子一樣,一個類照鏡子後,鏡子裡的類物件就是一個Class物件。它描述了這個類的所有屬性、方法等。
作用
可以在程式執行過程中,操作這些物件的屬性、方法等。
使用
說著其實是挺抽象的,那我們直接通過例子來了解反射
當一個類從JAVA程式碼到被new出來後,這中間是經歷了三個階段。
Source原始碼階段:Person.java檔案通過JAVAC編譯後,成為了Person.class位元組碼檔案,此時兩個檔案還存在硬碟上,並沒有進記憶體。
Class類物件階段:把class位元組碼檔案通過類載入器ClassLoader載入進了記憶體,生成了一個Class類物件,Class類物件把Person.class中的所有屬性、方法等都進行了一次封裝。
Runtime執行時階段:也就是new出了一個物件的階段,此物件參與了程式的執行。
獲取Class物件的三種方式
-
Class.forName("全類名"):將位元組碼檔案載入進記憶體,返回Class物件
-
類名.class:通過類名的屬性class獲取
-
物件.getClass():getClass()方法在Object類中定義著。
注意:
1)同一個位元組碼檔案(*.class)在一次程式執行過程中,只會被載入一次,不論通過哪一種方式獲取的Class物件都是同一個。
2)因為靜態程式碼塊是在類載入的時候執行,所以如果類中包含靜態程式碼塊,那麼除了Person.class這種方法外的另外兩種方法,都會造成靜態程式碼塊的執行,且只執行一次。
獲取成員變數
1.獲取public 修飾的成員變數
Field[] getFields() :獲取所有 public 修飾的成員變數
Field getField(String name) 獲取指定名稱的 public 修飾的成員變數
2.獲取任意的成員變數
Field[] getDeclaredFields() 獲取所有的成員變數,不考慮修飾符
Field getDeclaredField(String name) 獲取指定名稱的的成員變數
獲取不是public許可權的成員變數需要是要暴力反射
獲取構造方法
1.獲取public 修飾的構造方法
Constructor<?>[] getConstructors() 獲取 public 修飾的空參構造方法
Constructor
2.獲取任意的構造方法
Constructor<?>[] getDeclaredConstructors() 無視修飾符獲取空參構造方法
Constructor
同樣要使用暴力反射
獲取成員方法
1.獲取public 修飾的構造方法method
Method[] getMethods() 獲取 public 修飾的空參方法method
Method getMethod(String name, 類<?>... parameterTypes) 獲取 public 修飾的有參方法method
2.獲取任意的method方法
Method[] getDeclaredMethods() 無視修飾符獲取空參方法
Method getDeclaredMethod(String name, 類<?>... parameterTypes) 無視修飾符獲取有參方法
同樣要使用暴力反射
獲取全類名
String getName()
反射建立物件的兩種方式
一、直接用Class類物件獲取對應例項
// 呼叫無參構造器 ,若是沒有,則會報異常
Class clazz = Class.forName("com.yyhuni.Person");
Object o = clazz.newInstance();
二、有帶引數的建構函式的類,先獲取到其構造物件,再通過該構造方法類獲取例項:
Class clazz = Class.forName("com.yyhuni.Person");
//獲取建構函式類的物件
Constroctor constroctor = clazz.getConstructor(String.class,Integer.class);
// 使用構造器物件的newInstance方法初始化物件
Object obj = constroctor.newInstance("yy", 18);
歡迎關注我的公眾號,同步更新喔