1. 程式人生 > 其它 >JAVA安全基礎之反射

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物件的三種方式

  1. Class.forName("全類名"):將位元組碼檔案載入進記憶體,返回Class物件

  2. 類名.class:通過類名的屬性class獲取

  3. 物件.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 getConstructor(類<?>... parameterTypes) 獲取 public 修飾的有參構造方法

2.獲取任意的構造方法

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

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

同樣要使用暴力反射

獲取成員方法

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); 

歡迎關注我的公眾號,同步更新喔