1. 程式人生 > >java反射-使用反射來操縱方法

java反射-使用反射來操縱方法

意思 static imp tar cati rac tac 你會 edm

一個類的主要成員時方法,辣麽我們通過反射獲取到一個類的所有方法信息後,總的尋找一種方式去操作調用這些方法,這樣反射才有意義有意思。

Method對象有一個方法invoke。 public Object invoke(Object obj, Object... args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException。 該方法的解釋API解釋為:

對帶有指定參數的指定對象調用由此 Method 對象表示的底層方法。個別參數被自動解包,以便與基本形參相匹配,基本參數和引用參數都隨需服從方法調用轉換。 
如果底層方法是靜態的,那麽可以忽略指定的 obj 參數。該參數可以為 null。 

如果底層方法所需的形參數為 0,則所提供的 args 數組長度可以為 0 或 null。 

如果底層方法是實例方法,則使用動態方法查找來調用它,這一點記錄在 Java Language Specification, Second Edition 的第 15.12.4.4 節中;在發生基於目標對象的運行時類型的重寫時更應該這樣做。 

如果底層方法是靜態的,並且尚未初始化聲明此方法的類,則會將其初始化。 

如果方法正常完成,則將該方法返回的值返回給調用者;如果該值為基本類型,則首先適當地將其包裝在對象中。但是,如果該值的類型為一組基本類型,則數組元素不 被包裝在對象中;換句話說,將返回基本類型的數組。如果底層方法返回類型為 void,則該調用返回 null。 

  下面我用ArrayList 類來做了一個測試:

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;

/**
 * java反射 工具類
 */
public class ClassUtil {
    
/** * 通過反射操作對象方法 */ public static void method() { try { // 本例中傳入的是ArrayList 對象,就以ArrayList 對象的add方法為例 ArrayList arrayList = new ArrayList(); // 1.獲取該類的類類型 Class c = arrayList.getClass(); // 2.獲取該類自己定義的所有方法 Method[] methods = c.getDeclaredMethods();
// 3.得到所有方法列表信息 for (Method method : methods) { System.out.print(method.getName() + "("); Class[] parameterTypes = method.getParameterTypes(); for (int i = 0, len = parameterTypes.length; i < len; i++) { System.out.print(parameterTypes[i].getName()); if (i != len - 1) { System.out.print(","); } } System.out.print(")\n"); } // 4.使用方法 invoke 來操作方法 add Method method = c.getMethod("add", new Class[]{Object.class}); method.invoke(arrayList, "測試1"); method.invoke(arrayList, 100); method.invoke(arrayList, 100.0f); // 5.測試打印 arrayList 對象 System.out.println("================" + arrayList); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { ClassUtil.method(); } }

  對於java集合中的泛型,是用於在編譯階段程序員輸入驗證的,我們可以通過反射的方式,來繞過這種輸入驗證。如上面的栗子,我們將 ArrayList<String> arrayList = new ArrayList(); 指定泛型為String類型,其他代碼不變,你會發現,打印輸出的結果還是一樣。

java反射-使用反射來操縱方法