【1】Method類簡介Java反射技術的一個基本應用之一就是在運行時期間動態地調用方法。要動態地調用方法,首先要獲得方法本身。步驟如下:
1.獲得Class對象
2.調用Class對象的getMethod(String, Class[])方法獲得指定的方法
getMethod方法的第一個參數用來指定方法的名稱,第二個參數是一個Class數組,用來存放代表各個參數類型的Class對象。這個方法有一個值得注意的地方:
如果參數類型是原子類型(int,long,short等),要使用諸如int.class,long.class來擷取其對應Class對象,而不能使用對應的封裝類對象。
在獲得Method對象之後,就可以在運行時動態地調用方法了。Method類裡面最主要的方法有以下幾種
1.擷取方法所在的類: getDeclaringClass()
2.擷取方法簽名中所有聲明的拋出異常:getExceptionTypes()
3.擷取方法簽名中所有參數的類型: getParameterTypes()
4.擷取方法簽名中傳回值的類型: getReturnType()
5.調用方法: Object invoke(Object obj, Object... args)
Method類的核心就是invoke方法,該方法用於Method對象喚
起對象中對應的方法,特別要注意的是第二個參數:通常這是一個Object數組,這意味著如果參數是原子類型資料,必須先把他轉換成對應的封裝類對
象,invoke方法會在後台自動將其解壓成原子類型。
從JDK1.5開始之後,增加了"自動裝箱"和"自動開箱"的功能,所以你可以看到在行61處,使用了原子類型資料而非封裝類來傳遞參數。如果是在JDK1.4或以下版本,則此處會報錯。建議不採用此種做法,以免出現資料類型完全的問題。
【2】使用反射拷貝對象的思路
1. 擷取來源物件的所有成員變數列表
2. 每次取出變數列表中的一個變數,擷取其getXxx()和setXxx(Type)方法名稱
3. 根據getXxx()和setXxx(Type)方法名稱獲得對應的Method對象
4. 來源物件通過invoke(Object, Class[])方法調用getXxx()方法,獲得成員變數的值
5. 目標對象通過invoke(Object, Class[])的方法的setXxx(Type)方法,為目標對象的成員變數賦值
其中關鍵的程式碼片段格式如下:
1. 建立Method對象:Class.getMethod(method name, method prameters class array)
2. 調用方法:method.invoke(object, method parameters class array)
【3】範例程式碼
// 獲得對象的所有屬性
Field fields[] = classType.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
String firstLetter = fieldName.substring(0, 1).toUpperCase();
// 獲得和屬性對應的getXXX()方法的名字
String getMethodName = "get" + firstLetter + fieldName.substring(1);
// 獲得和屬性對應的setXXX()方法的名字
String setMethodName = "set" + firstLetter + fieldName.substring(1);
// 獲得和屬性對應的getXXX()方法
Method getMethod = classType.getMethod(getMethodName,
new Class[] {});
// 獲得和屬性對應的setXXX()方法,使用filed對象的類型
Method setMethod = classType.getMethod(setMethodName,
new Class[] { field.getType() });
// 調用原對象的getXXX()方法:指定調用的對象和方法的參數值列表
Object value = getMethod.invoke(object, new Object[] {});
System.out.println(fieldName + ":" + value);
// 調用拷貝對象的setXXX()方法:指定調用的對象和參數值列表(注意必須是Object類型)
setMethod.invoke(objectCopy, new Object[] { value });
}