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 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);
歡迎關注我的公衆号,同步更新喔