一個java.lang.reflect.Method對象提供關於類或者接口上單個方法的信息訪問,所反射的方法可以是類方法或實例方法(包括抽象方法);一個Method方法匹配實際參數時允許加寬轉換,但是如果調用實際參數時變窄轉換將會拋出IllegalArgumentException異常;
1.獲取Method對象的方法有四種,如下示例:
package reflect;
import java.lang.reflect.Method;
public class MethodTest {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Class<?> clazz = MethodTest.class;
/**
* 返回Method數組對象,對應Class對象的所有的公共方法,
* 包括當前類、繼承的父類、實現的接口聲明的所有方法;
*
* 返回的數組中的元素沒有排序,沒有任何特定的順序;
*
* 如果當前的Class對象代表的類、接口或者原始數據類型、void類型沒有public類型的方法,
* 將會返回一個長度爲0的數組;
*/
Method[] methods = clazz.getMethods();
for(Method method : methods) {
System.out.println(method.getName());
}
System.out.println("-----------getDeclaredMethods-----------------------------");
/**
* 返回Method數組對象,對應Class對象的所有的public、protected、default、private方法,
* 但是不包括繼承的父類、實現的接口聲明的所有方法;
*
* 返回的數組中的元素沒有排序,沒有任何特定的順序;
*
* 如果當前的Class對象代表的類、接口或者原始數據類型、void類型沒有public類型的方法,
* 將會返回一個長度爲0的數組;
*/
Method[] methods1 = clazz.getDeclaredMethods();
for(Method method1 : methods1) {
System.out.println(method1.getName());
}
System.out.println("----------getMethod------------------------------");
/**
* 返回類、接口中聲明的Method對象,若果同一個類、接口中聲明瞭一個以上的具有相同
* 參數類型的方法,並且其中一個方法具有比其它任何類型更具體的返回類型,則返回該
* 方法;否則,任意選擇一個方法返回;
*
* 如果在類、接口中沒有搜索到對應的方法,則向它的父類、父接口去搜索,搜索邏輯如上;
*/
Method method2 = clazz.getMethod("setAge", new Class[] {int.class});
System.out.println(method2.getName());
System.out.println("--------------getDeclaredMethod--------------------------");
/**
* 返回在指定Class對象或者接口中聲明的Method對象;如果同一個類中聲明瞭一個以上的具有相同
* 參數類型的方法,並且其中一個方法具有比其它任何類型更具體的返回類型,則返回該方法;否則,
* 任意選擇一個方法返回;
*
*/
Method method3 = clazz.getDeclaredMethod("setAge", new Class[] {int.class});
System.out.println(method3.getName());
}
}
2.Method對象中方法詳解
- 獲取Method對象
Class<?> clazz = MethodTest.class;
Method method = clazz.getDeclaredMethod("setAge", new Class[] {int.class});
- getName
//返回由Method對象表示的方法名稱,以字符串形式返回。
String methodName = method.getName();
- setAccessible
/**
* 如果flag設置爲true,將會抑制安全檢查器;如果爲false,安全檢查器將會校驗訪問的安全性;
* 也就是控制通過Method對象是否可以訪問類、接口中私有的成員變量
*/
method.setAccessible(true);
- getReturnType
/**
* 返回一個此對象表示的方法的返回類型的Class對象
* 返回:此對象表示的方法的返回類型
*/
Class<?> returnType = method.getReturnType();
- getClass
/**
* 返回當前Method對象運行時的class對象,返回的class對象將會被Method方法對象鎖定(synchronized)
*
* return java.lang.reflect.Method
*/
Class<?> cla = method.getClass();
- getDeclaringClass
/**
* 返回聲明當前類或接口對應方法所代表的的Class實例對象;
* return reflect.MethodTest
*/
Class<?> claz = method.getDeclaringClass();
- getTypeParameters
/**
* 返回方法對象聲明的類型變量數組GenericDeclaration,數組的順序按照聲明的順序返回;
* 如果沒有聲明類型變量將會返回數組長度爲0的TypeVariable數組;
*/
TypeVariable<Method>[] variable = method.getTypeParameters();
- invoke
MethodTest obj = new MethodTest();
/**
* 調用由這個方法對象表示的基礎方法,具有指定參數的指定對象;單個參數會自動的解包以匹配原始
* 類型參數,並且原始和引用類型參數都在必要是服從方法調用的類型轉換;
*
* 如果基礎方法是靜態的,則忽略指定的參數,他可能爲null;
*
* 如果基礎方法所需的形式參數數量爲0,則提供的參數數組可以爲長度爲0的數組或者null;
*
* 如果基礎方法是實例方法,則使用Java語言規範(第二版第152.4.4節)中所記錄的動態方法查找來調用;
* 特別是,將基於目標對象的運行時類型重寫。
*
* 如果基礎方法是靜態的,則聲明該方法的類如果尚未初始化則初始化。
*
* 如果該方法正常完成,返回的值將返回給調用方的調用方;如果該值具有一個原始類型,
* 則它首先被適當地包裹在一個對象中。但是,如果值具有原始類型數組的類型,則數組中
* 的元素是包在對象中的<i>不</i>;換句話說,返回一個原始類型數組。如果基礎方法返回類型無效,
* 則調用返回null。
*
* @param obj 調用基礎方法的對象;
* @param args方法調用中使用的參數;
* @return 將該對象表示的方法使用給定參數調用的結果;
*
* @exception IllegalAccessException、IllegalArgumentException、InvocationTargetException
* 、NullPointerException、ExceptionInInitializerError
*/
Object result = method.invoke(obj, 1);
- isVarArgs
/**
* 如果該方法被聲明爲可以接受可變長的參數,則返回true,否則返回false;
*/
boolean varArgs = method.isVarArgs();
- isSynthetic
/**
* 如果該方法是複合方法,則返回true,否則返回false;
*/
boolean synthetic = method.isSynthetic();
- isAccessible
/**
* 判斷對象表示的方法是否可以訪問,如果可以返回true,否則返回false;
*/
boolean accessible = method.isAccessible();
- isBridge
/**
* 如果此方法是一個橋方法,則返回true,否則返回false;
*/
boolean bridge = method.isBridge();
- getModifiers
/**
* 返回由該方法對象表示的方法的java語言修飾符;作爲整數,應該使用Modifier
* 類來對其進行解碼
*/
int code = method.getModifiers();
- getExceptionTypes
/**
* 返回一個類對象數組,該數組表示由該基礎方法引發的異常類型
*/
Class<?>[] eclassz = method.getExceptionTypes();