Java反射Reflect之java.lang.reflect.Method類詳解

一個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();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章