Java反射APIJava反射指的是在運行狀態(tài)時,能夠獲取類的屬性和方法或者修改類運行時行為的過程。 java.lang.Class類提供了很多方法用于獲取元數(shù)據(jù),、檢查和改變類運行時的行為。 Java的反射主要涉及java.lang和java.lang.reflect包下的類,。 反射應(yīng)用場景舉例- IDE, 如Eclipse,、MyEclipse、NetBeans等,;
- 調(diào)試器;
- 測試工具等,;
- 各大框架,、spring、hibernate等,;
java.lang.Class類java.lang.Class主要提供了以下兩個功能: - 提供方法用于訪問運行期間類的元數(shù)據(jù),;
- 提供方法用于檢查和修改類的運行時行為,;
java.lang.Class類常用方法Method | Description |
---|
1) public String getName() | 返回類名 | 2) public static Class forName(String className)throws ClassNotFoundException | 加載類并返回Class對象 | 3) public Object newInstance()throws InstantiationException,IllegalAccessException | 創(chuàng)建實例對象 | 4) public boolean isInterface() | 判斷是否是接口 | 5) public boolean isArray() | 判斷是否是數(shù)組 | 6) public boolean isPrimitive() | 判斷是否是原始數(shù)據(jù)類型 | 7) public Class getSuperclass() | 返回父類Class引用 | 8) public Field[] getDeclaredFields()throws SecurityException | 返回類的成員屬性字段數(shù)組 | 9) public Method[] getDeclaredMethods()throws SecurityException | 返回類的方法數(shù)組 | 10) public Constructor[] getDeclaredConstructors()throws SecurityException | 返回類的構(gòu)造方法數(shù)組 | 11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException | 返回類中指定參數(shù)類型的方法 |
怎樣獲取Class對象有三種方式,如下: - Class類的forName()方法,,動態(tài)加載,,運行時,開始裝入類, 并做類的靜態(tài)初始化
- 對象的getClass()方法,,靜態(tài)加載(編譯時已加載)
- .class語法,, 靜態(tài)加載(編譯時已加載)
forName()方法示例 可用于動態(tài)加載,當你知道類的全限定名時,,可以使用該方式,。注意原始數(shù)據(jù)類型不適用該方法; package tmp;class Simple{}public class Test{ public static void main(String args[]) throws ClassNotFoundException { Class?> c = Class.forName('tmp.Simple'); System.out.println(c.getName()); System.out.println(c.getSimpleName()); }} tmp.Simple SimplegetClass()方法示例: 從實例對象中獲取Class對象 package tmp;class Simple{}public class Test{ void printName(Object obj) { } public static void main(String args[]) { Simple s = new Simple(); Class?>extends Object> c = s.getClass(); System.out.println(c.getName()); System.out.println(c.getSimpleName()); }} tmp.Simple Simple.class語法示例 作用于類名上,,也可應(yīng)用于原始數(shù)據(jù)類型,,如下所示: package tmp;public class Test{ public static void main(String args[]) { Class c = boolean.class; System.out.println(c.getName()); Class c2 = Test.class; System.out.println(c2.getName()); }} boolean tmp.Test判斷Class對象對應(yīng)的類型以下方法可用于判斷Class對象對應(yīng)的類型: 1) public boolean isInterface(): 是否對應(yīng)接口 | 2) public boolean isArray(): 是否對應(yīng)數(shù)組 | 3) public boolean isPrimitive(): 是否對應(yīng)原始數(shù)據(jù)類型 |
代碼示例: package tmp;class Simple{}interface My{}public class Test{ public static void main(String args[]) { try { Class?> c = Class.forName('tmp.Simple'); System.out.println(c.isInterface()); Class?> c2 = Class.forName('tmp.My'); System.out.println(c2.isInterface()); } catch (Exception e) { System.out.println(e); } }} false true通過反射創(chuàng)建實例對象有兩種方式,如下: - 通過Class對象的newInstance()方法創(chuàng)建,,這種方式只能調(diào)用無參構(gòu)造方法,;
- 通過Constructor對象的newInstance()方法創(chuàng)建,,這種方式適用于有參構(gòu)造方法,并且還可以破壞單例模式,調(diào)用私有構(gòu)造方法,;
所以,通常來講,,第二種方式比第一種使用范圍更廣,。 Class對象調(diào)用newInstance()方法示例 package tmp;class Simple{ void message() { System.out.println('Hello Java'); }}public class Test{ public static void main(String args[]) { try { Class?> c = Class.forName('tmp.Simple'); Simple s = (Simple) c.newInstance(); s.message(); } catch (Exception e) { System.out.println(e); } }} Hello JavaConstructor對象調(diào)用newInstance()方法示例 注意這里可以根據(jù)傳入?yún)?shù)的類型來得到指定的構(gòu)造方法,還可以改變構(gòu)造方法的訪問權(quán)限限制,。 package tmp;import java.lang.reflect.Constructor;class Simple{ private String msg; void message() { System.out.println('Hello Java,' + msg); } private Simple(String s){ this.msg = s; }}public class Test{ public static void main(String args[]) { try { Class?> c = Class.forName('tmp.Simple'); Constructor?> con = c.getDeclaredConstructor(String.class); con.setAccessible(true); Simple s = (Simple) con.newInstance('...'); s.message(); } catch (Exception e) { System.out.println(e); } }} Hello Java,...通過反射調(diào)用私有方法通過反射,,我們可以調(diào)用其它類的私有方法,主要涉及java.lang.Class和java.lang.reflect.Method類,; 其中主要是用到了Method類的setAccessible方法和invoke方法,,前者修改訪問權(quán)限,后者調(diào)用方法,。 通過調(diào)用有參私有方法示例: 關(guān)于javap工具使用javap命令可以反匯編java的字節(jié)碼文件,,展示class文件中的字段屬性、構(gòu)造方法,、普通方法信息,; 使用說明: javap java.lang.Object示例 javap -c Test示例: 寫個簡單的Test類,如下: package tmp;class Simple{}public class Test{ public static void main(String args[]) { System.out.println('Hello'); }} 輸入javap -c Test: 參考資料基本屬于翻譯,,做了小部分修改 http://www./java-reflection
|