天天看點

JAVA安全基礎之反射

JAVA安全基礎之反射

在JAVA安全中,反射是一個經常使用的技術,是以熟悉使用反射是非常必要的。下面就簡單的講下JAVA的反射的用法

什麼是反射

每個類都有對應的Class類對象,該Class類對象包含該類的屬性、方法等資訊,這個Class類對象就是這個類的反射。

就像鏡子一樣,一個類照鏡子後,鏡子裡的類對象就是一個Class對象。它描述了這個類的所有屬性、方法等。

作用

可以在程式運作過程中,操作這些對象的屬性、方法等。

使用

說着其實是挺抽象的,那我們直接通過例子來了解反射

當一個類從JAVA代碼到被new出來後,這中間是經曆了三個階段。

JAVA安全基礎之反射

Source源代碼階段:Person.java檔案通過JAVAC編譯後,成為了Person.class位元組碼檔案,此時兩個檔案還存在硬碟上,并沒有進記憶體。

Class類對象階段:把class位元組碼檔案通過類加載器ClassLoader加載進了記憶體,生成了一個Class類對象,Class類對象把Person.class中的所有屬性、方法等都進行了一次封裝。

Runtime運作時階段:也就是new出了一個對象的階段,此對象參與了程式的運作。

擷取Class對象的三種方式

  1. Class.forName("全類名"):将位元組碼檔案加載進記憶體,傳回Class對象
  2. 類名.class:通過類名的屬性class擷取
  3. 對象.getClass():getClass()方法在Object類中定義着。

注意:

1)同一個位元組碼檔案(*.class)在一次程式運作過程中,隻會被加載一次,不論通過哪一種方式擷取的Class對象都是同一個。

2)因為靜态代碼塊是在類加載的時候執行,是以如果類中包含靜态代碼塊,那麼除了Person.class這種方法外的另外兩種方法,都會造成靜态代碼塊的執行,且隻執行一次。

JAVA安全基礎之反射

擷取成員變量

1.擷取public 修飾的成員變量

Field[] getFields() :擷取所有 public 修飾的成員變量

Field getField(String name) 擷取指定名稱的 public 修飾的成員變量

2.擷取任意的成員變量

Field[] getDeclaredFields() 擷取所有的成員變量,不考慮修飾符

Field getDeclaredField(String name) 擷取指定名稱的的成員變量

擷取不是public權限的成員變量需要是要暴力反射

JAVA安全基礎之反射

擷取構造方法

1.擷取public 修飾的構造方法

Constructor<?>[] getConstructors() 擷取 public 修飾的空參構造方法

Constructor getConstructor(類<?>... parameterTypes) 擷取 public 修飾的有參構造方法

2.擷取任意的構造方法

Constructor<?>[] getDeclaredConstructors() 無視修飾符擷取空參構造方法

Constructor getDeclaredConstructor(類<?>... parameterTypes) 無視修飾符擷取有參構造方法

同樣要使用暴力反射

JAVA安全基礎之反射

擷取成員方法

1.擷取public 修飾的構造方法method

Method[] getMethods() 擷取 public 修飾的空參方法method

Method getMethod(String name, 類<?>... parameterTypes) 擷取 public 修飾的有參方法method

2.擷取任意的method方法

Method[] getDeclaredMethods() 無視修飾符擷取空參方法

Method getDeclaredMethod(String name, 類<?>... parameterTypes) 無視修飾符擷取有參方法

JAVA安全基礎之反射

擷取全類名

String getName()

JAVA安全基礎之反射

反射建立對象的兩種方式

一、直接用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); 
           

歡迎關注我的公衆号,同步更新喔

JAVA安全基礎之反射