C語言中文網 目錄
首頁 > Java教程 > Java反射機制 閱讀:1,167

Java反射在類中的應用:通過反射執行方法(獲取方法)

動態獲取一個對象方法的信息,首先需要通過下列方法之一創建一個 Method 類型的對象或者數組。
  • getMethods()
  • getMethods(String name,Class<?> …parameterTypes)
  • getDeclaredMethods()
  • getDeclaredMethods(String name,Class<?>...parameterTypes)

如果是訪問指定的構造方法,需要根據該方法的入口參數的類型來訪問。例如,訪問一個名稱為 max,入口參數類型依次為 int 和 String 類型的方法。

下面的兩種方式均可以實現:
objectCiass.getDeclaredConstructor("max",int.class,String.class);
objectClass.getDeclaredConstructor("max",new Ciass[]{int.class,String.class});

Method 類的常用方法如表 3 所示。

表1 Method類的常用方法
靜態方法名稱 說明
getName() .獲取該方法的名稱
getParameterType() 按照聲明順序以 Class 數組的形式返回該方法各個參數的類型
getRetumType() 以 Class 對象的形式獲得該方法的返回值類型
getExceptionTypes() 以 Class 數組的形式獲得該方法可能拋出的異常類型
invoke(Object obj,Object...args) 利用 args 參數執行指定對象 obj 中的該方法,返回值為 Object 類型
isVarArgs() 查看該方法是否允許帶有可變數量的參數,如果允許返回 true,否 則返回 false
getModifiers() 獲得可以解析出該方法所采用修飾符的整數

例 2

下面通過一個案例來演示如何調用 Method 類的方法獲取動態類中方法的信息。

(1) 首先創建一個 Book1 類,并編寫 4 個具有不同作用域的方法。Book1 類的最終代碼如下:
package ch12;
public class Book1
{
    //static 作用域方法
    static void staticMethod()
    {
        System.out.println("執行staticMethod()方法");
    }
    //public 作用域方法
    public int publicMethod(int i)
    {
        System.out.println("執行publicMethod()方法");
        return 100+i;
    }
    //protected 作用域方法
    protected int protectedMethod(String s,int i)throws NumberFormatException
    {
        System.out.println("執行protectedMethod()方法");
        return Integer.valueOf(s)+i;
    }
    //private 作用域方法
    private String privateMethod(String ...strings)
    {
        System.out.println("執行privateMethod()方法");
       
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<sb.length();i++)
        {
            sb.append(strings[i]);
        }
        return sb.toString();
    }
}

(2) 編寫測試類 Test02,在該類的 main() 方法中通過反射訪問 Book1 類中的所有方法,并將該方法是否帶可變類型參數、入口參數類型和可能拋出的異常類型信息輸出到控制臺。

Test02 類的代碼如下:
package ch12;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test02
{
    public static void main(String[] args)
    {
        //獲取動態類Book1
        Book1 book=new Book1();
        Class class1=book.getClass();
        //獲取Book1類的所有方法
        Method[] declaredMethods= class1.getDeclaredMethods();
        for(int i=0;i<declaredMethods.length;i++)
        {
            Method method=declaredMethods[i];
            System.out.println("方法名稱為:"+method.getName());
            System.out.println("方法是否帶有可變數量的參數:"+method.isVarArgs());
            System.out.println("方法的參數類型依次為:");
            //獲取所有參數類型
            Class[] methodType=method.getParameterTypes();
            for(int j=0;j<methodType.length;j++)
            {
                System.out.println(" "+methodType[j]);
            }
            //獲取返回值類型
            System.out.println("方法的返回值類型為:"+method.getReturnType());
            System.out.println("方法可能拋出的異常類型有:");
            //獲取所有可能拋出的異常
            Class[] methodExceptions=method.getExceptionTypes();
            for(int j=0;j<methodExceptions.length;j++)
            {
                System.out.println(" "+methodExceptions[j]);
            }
            boolean isTurn=true;
            while(isTurn)
            {
                try
                {    //如果該成員變量的訪問權限為private,則拋出異常
                    isTurn =false;
                    if(method.getName().equals("staticMethod"))
                    {    //調用沒有參數的方法
                        method.invoke(book);
                    }
                    else if(method.getName().equals("publicMethod"))
                    {    //調用一個參數的方法
                        System.out.println("publicMethod(10)的返回值為:"+method.invoke(book,10));
                    }
                    else if(method.getName().equals("protectedMethod"))
                    {    //調用兩個參數的方法
                        System.out.println("protectedMethod(\"10\",15)的返回值為:"+method.invoke(book,"10",15));
                    }
                    else if(method.getName().equals("privateMethod"))
                    {    //調用可變數量參數的方法
                        Object[] parameters=new Object[]{new String[]{"J","A","V","A"}};
                        System.out.println("privateMethod()的返回值為:"+method.invoke(book,parameters));
                    }
                }
                catch (Exception e)
                {
                    System.out.println("在設置成員變量值時拋出異常,下面執行setAccessible()方法");
                    method.setAccessible(true);    //設置為允許訪問private方法
                    isTurn = true;
                   
                }
            }
            System.out.println("=============================\n");
        }
    }
}

(3) 運行測試類 test02,程序將會依次動態訪問 Book1 類中的所有方法。訪問 staticMethod() 方法的運行效果如下所示:
方法名稱為:staticMethod
方法是否帶有可變數量的參數:false
方法的參數類型依次為:
方法的返回值類型為:void
方法可能拋出的異常類型有:
執行staticMethod()方法
=============================

訪問 publicMethod() 方法的運行效果如下所示:
方法名稱為:publicMethod
方法是否帶有可變數量的參數:false
方法的參數類型依次為:
int
方法的返回值類型為:int
方法可能拋出的異常類型有:
執行publicMethod()方法
publicMethod(10)的返回值為:110
=============================

訪問 protectedMethod() 方法的運行效果如下所示:
方法名稱為:protectedMethod
方法是否帶有可變數量的參數:false
方法的參數類型依次為:
class java.lang.String
int
方法的返回值類型為:int
方法可能拋出的異常類型有:
class java.lang.NumberFormatException
執行protectedMethod()方法
protectedMethod("10",15)的返回值為:25
=============================

訪問 privateMethod() 方法的運行效果如下所示:
方法名稱為:privateMethod
方法是否帶有可變數量的參數:true
方法的參數類型依次為:
class java.lang.String;
方法的返回值類型為:class java.lang.String
方法可能拋出的異常類型有:
在設置成員變量值時拋出異常,下面執行setAccessible()方法
執行privateMethod()方法
privateMethod()的返回值為:
=============================

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo