標籤:demo out 訪問 能力 個數 成員變數 file illegal led
反射機制的作用
一般機制是java知道類的定義(比如import了這個類,或者就在同一個包裡),然後根據類定義去new一個執行個體出來。而反射機制是不知道類是什麼樣的,根據字串之類的類名字等去擷取一個執行個體,然後根據方法名字去執行方法。好比說,一般情況下畫一隻老虎,我得Crowdsourced Security Testing道老虎長什麼樣子才能畫出來;有了反射機制,我只要知道“老虎”這個名字就能畫出來,可以知道老虎吃什麼,有什麼能力,有什麼屬性。
反射機制的功能
(這些類都位於java.lang.reflect包中)
Class類:代表一個類。(java.lang.Object java.lang.Class<T>T - 由此 Class 對象建模的類的類型。例如,String.class 的類型是 Class<String>。如果將被建模的類未知,則使用 Class<?>。)
Field類:代表類的成員變數(提供有關類或介面的單個欄位的資訊,以及對它的動態存取權限。反射的欄位可能是一個類(靜態)欄位或執行個體欄位。)
Method類:代表類的方法。(Method 提供關於類或介面上單獨某個方法(以及如何訪問該方法)的資訊。所反映的方法可能是類方法或執行個體方法(包括抽象方法)。)
Construct類:代表類的構造方法。(提供關於類的單個構造方法的資訊以及對它的存取權限。)
Array類:提供動態建立數組,以及訪問數組中元素的靜態方法。
建立測試類別
package com.gqx.Reflect;class Person {private String name;public int age; public int add(int para1,int para2){return para1+para2;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} public String toString(){ return "["+this.name+" "+this.age+"]"; } public Person(String name, int age) { this.age=age; this.name=name; } public Person() { } public String say(String message){ return message; } }
以下開始使用
java.lang.Object java.lang.Class<T>的方法
package com.gqx.Reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class Demo3 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException {// TODO Auto-generated method stub//擷取類的Class對象Class<?> demo1=Class.forName("com.gqx.Reflect.Person");Class<?> demo2=new Person().getClass();Class<?> demo3=Person.class;/** * 擷取Field */// 使用getFields擷取屬性(公用欄位的 Field 對象的數組) Field[] fields = demo1.getFields(); for (Field f : fields) { System.out.println(f); } // 使用getDeclaredFields擷取屬性 fields = demo1.getDeclaredFields(); for (Field f : fields) { System.out.println(f); } /** * 擷取類的Method */System.out.println("===============類的全部方法===============");//返回一個包含某些 Method 對象的數組,這些對象反映此 Class 對象所表示的類或介面//(包括那些由該類或介面聲明的以及從超類和超介面繼承的那些的類或介面)的公用 member 方法。Method[] method = demo1.getMethods(); for (int i = 0; i < method.length; ++i) { Class<?> returnType = method[i].getReturnType(); Class<?> para[] = method[i].getParameterTypes(); int temp = method[i].getModifiers(); //取得修飾符 System.out.print(Modifier.toString(temp) + " "); //取得傳回型別 System.out.print(returnType.getName() + " "); //取得方法名稱 System.out.print(method[i].getName() + " "); System.out.print("("); //取得c參數 for (int j = 0; j < para.length; ++j) { System.out.print(para[j].getName() + " " + "arg" + j); if (j < para.length - 1) { System.out.print(","); } } //是否存在異常 Class<?> exce[] = method[i].getExceptionTypes(); if (exce.length > 0) { System.out.print(") throws "); for (int k = 0; k < exce.length; ++k) { System.out.print(exce[k].getName() + " "); if (k < exce.length - 1) { System.out.print(","); } } } else { System.out.print(")"); } System.out.println(); }System.out.println(); /** * 擷取類的Constructor */System.out.println("*****************");// 使用getDeclaredConstructors擷取構造器 //返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的所有公用構造方法。Constructor<?>[] constructors = demo1.getConstructors(); for (Constructor<?> m : constructors) { System.out.println(m); }// 使用getDeclaredConstructors擷取構造器 constructors = demo1.getDeclaredConstructors(); for (Constructor<?> m : constructors) { System.out.println(m); } /** * 建立類的執行個體 */System.out.println("*****************");//想調用方法,必須去獲得method方法/** * getMethod(String name, Class<?>... parameterTypes) *返回一個 Method 對象,它反映此 Class 對象所表示的類或介面的指定公用成員方法。 *String:方法的名字, *Class<?>... parameterTypes:該方法需要接受的參數,數組的形式, *因為java中的方法會根據參數個數容易出現重載。 */Object demo=demo3.newInstance();Method addMethod=demo3.getMethod("add",new Class[ ]{int.class,int.class} );Object result=addMethod.invoke(demo, new Object[]{1,2});System.out.println((Integer)result);/** * 擷取某個類的全部屬性 */System.out.println("===============本類屬性===============");Field[] field = demo1.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 許可權修飾符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 屬性類型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("==========私人的屬性=========="); // 取得實現的介面或者父類的屬性 Field[] filed1 = demo1.getFields(); for (int j = 0; j < filed1.length; j++) { // 許可權修飾符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 屬性類型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } }}
通過反射機制操作某個類的屬性
package com.gqx.Reflect;import java.lang.reflect.Field;public class Demo4 {private String proprety = null;public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {// TODO Auto-generated method stubClass<?> clazz = Class.forName("com.gqx.Reflect.Demo4"); Object obj = clazz.newInstance(); // 可以直接對 private 的屬性賦值 Field field = clazz.getDeclaredField("proprety"); field.setAccessible(true); field.set(obj, "Java反射機制"); System.out.println(field.get(obj));}}
Java反射機制