溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用反射調(diào)用方法

發(fā)布時間:2021-10-14 10:48:02 來源:億速云 閱讀:152 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“如何使用反射調(diào)用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何使用反射調(diào)用方法”吧!

反射調(diào)用構(gòu)造方法

在一個類中除了有繼承的關(guān)系外,最為重要的操作就是類中的結(jié)構(gòu)處理了,而類中的結(jié)構(gòu)首先需要觀察的就是構(gòu)造方法的使用問題,實際上在之前通過反射實例化對象的時候就已經(jīng)接觸到構(gòu)造方法的問題了:
實例化方法替代:clazz.getDeclaredConstructor().newInstance()
所有類的構(gòu)造方法的獲取都可以直接通過Class類來完成,該類中定義有如下的幾個方法:
獲取所有構(gòu)造方法:
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
獲取指定構(gòu)造方法:
public Constructor<T> getConstructor() throws SecurityException
獲取所有構(gòu)造方法:
public Constructor<?>[] getConstructors()throws SecurityException
獲取指定構(gòu)造方法:
public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

范例:修改Person類的定義
AbstractBase:

public abstract class AbstractBase {public AbstractBase() {}public AbstractBase(String msg) {}
}

Person:

public class Person extends AbstractBase implements  IChannelService,IMessageService {public Person() {}public Person(String name, int age) {
}

范例:獲取構(gòu)造
JavaAPIDemo

public class JavaAPIDemo {public static void main(String[] args) {
        Class<?> cls = Person.class;//獲取指定類的Class對象Constructor<?>[] constructors = cls.getDeclaredConstructors();  //獲取全部構(gòu)造for (Constructor<?> cons : constructors) {
            System.out.println(cons);
        }
    }
}//執(zhí)行結(jié)果:public cn.mldn.vo.Person()//public cn.mldn.vo.Person(java.lang.String,int)

此時獲取的是類中的全部構(gòu)造方法,但是也可以獲取一個指定參數(shù)的構(gòu)造。例如:現(xiàn)在的Person類之中有兩個構(gòu)造方法:
修改Person:

public class Person extends AbstractBase implements  IChannelService,IMessageService {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;
    }public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }
    @Overridepublic String toString() {return "姓名:" + this.name + "、年齡:" + this.age;
    }
}

此時調(diào)用Person類中的有參構(gòu)造方法進行Person類對象實例化,此時必須指明要調(diào)用的構(gòu)造,而后通過Constructor類中提供的實例化方法操作:
public T newInstance(Object... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException

范例:調(diào)用指定構(gòu)造實例化對象

import java.lang.reflect.Constructor;public class JavaAPIDemo {public static void main(String[] args) throws Exception {
        Class<?> cls = Person.class;
        Constructor<?> constructor = cls.getConstructor(String.class, int.class);Object obj = constructor.newInstance("小強", 78);
        System.out.println(obj);  //姓名:小強、年齡:78}
}

雖然程序代碼本身允許開發(fā)者調(diào)用有參構(gòu)造,但是如果從實際的開發(fā)角度出發(fā),所有使用反射的類中最好使用無參構(gòu)造,因為這樣的實例化可以達到統(tǒng)一性。

反射調(diào)用普通方法

在進行反射處理的時候也可以通過反射來獲取類之中的全部方法,但是需要提醒的是,如果想通過反射調(diào)用這些方法,必須有一個前提條件:類之中要提供實例化對象。
在Class類中提供了如下的操作可以獲取方法對象:

獲取全部方法:
public Method[] getMethods() throws SecurityException
獲取指定方法:
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
獲取本類全部方法:
public Method[] getDeclaredMethods() throws SecurityException
獲取本類指定方法:
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
范例:獲取全部方法

import java.lang.reflect.Method;public class JavaAPIDemo {public static void main(String[] args) throws Exception {Class<?> cls = Person.class;
        {Method methods [] = cls.getMethods();//獲取全部方法(包括父類中的方法)for (Method met : methods){System.out.println(met);
            }
        }System.out.println("---------------難以忘懷的愚人節(jié)的分割線-----------")
        {  // 獲取本類方法Method methods [] = cls.getDeclaredMethods();for (Method met : methods){System.out.println(met);
        }

        }
    }

執(zhí)行結(jié)果:
如何使用反射調(diào)用方法
但是需要注意的是,這時的方法信息的獲取是依靠Method類提供的toString()方法完成的,很多時候也可以由用戶來拼湊方法信息的展示形式。
范例:自定義方法信息顯示

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Person.class;  // 獲取指定類的Class對象Method methods[] = cls.getMethods();
        for (Method met:methods){int mod=met.getModifiers();//修飾符System.out.print(Modifier.toString(mod)+">);System.out.print(met.getReturnType().getName()+" ");System.out.print(met.getName()+"(");
            Class<?> params [] = met.getParameterTypes();//獲取參數(shù)類型for (int x = 0; x < params.length; x ++) {System.out.print(params[x].getName() + " " + "arg-" + x);if(x < params.length - 1) {System.out.println(",");
                }
            }System.out.print(")");class<?> exp [] = met.getExceptionTypes();if(exp.length > 0) {System.out.print("throws");
            }
            for(int x = 0 ; x < exp.length ; x ++) {System.out.print(exp[x].getName());if(x < exp.length - 1) {System.out.println(",");
                }
            }System.out.println();  //換行}
    }
}

這種代碼只需要清楚可以根據(jù)反射獲取方法的結(jié)構(gòu)即可,不需要過多深入了解,但在Method類中有一個致命的重要方法:
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

在Person類里面為name屬性追加有setter、getter方法。

public class Person extends AbstractBase implements  IChannelService,IMessageService {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;
    }public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }// 其他操作代碼略}

需要通過反射機制來實現(xiàn)Person類之中的setter與getter方法的調(diào)用處理。
范例:在不導(dǎo)入指定類開發(fā)包的情況下實現(xiàn)屬性的配置

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("cn.mladn.vo.Person"); //獲取指定類的Class對象// String attribute = "name"; //要操作的類屬性String value = "小強子";  //要設(shè)置的屬性內(nèi)容//1.任何情況下如果要想保存類中的屬性或者調(diào)用類中的方法都必須保證存在有實例化對象,既然不允許導(dǎo)入包,那么就反射實例化Object obj = cls.getDeclaredConstructor().newInstance();  //調(diào)用無參構(gòu)造實例化//2.如果要想進行方法的調(diào)用,那么一定要獲取方法的名稱String setMethodName = "setName";  //方法名稱 Method method = cls.getDeclaredMethodsetMethodName, String.class);   //獲取指定的方法method.invoke(obj, value);  //等價于:Person對象.setName(value);String getMethodName="getName";method=cls.getDeclaredMethod(getMethodName);   //getter沒有參數(shù)System.out.println(getMethod.invoke(obj););  //等價于:Person對象.getName();} 
}

利用此類操作整體的形式上不會有任何明確的類對象產(chǎn)生,一切都是依靠反射機制處理的,這樣的處理避免了與某一個類耦合問題。

到此,相信大家對“如何使用反射調(diào)用方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI