更新時(shí)間:2019-08-21 11:38:57 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2670次
動(dòng)力節(jié)點(diǎn)java學(xué)院小編今天為大家介紹Java反射獲取方法以及調(diào)用方法。希望看完此文后對(duì)大家有幫助,下面就隨小編一起來看看Java反射獲取方法以及調(diào)用方法吧。
java反射獲取方法
1、先找到方法所在類的字節(jié)碼
2、找到需要被獲取的方法
Class類中獲取方法:
public Method[] getMethods();//獲取包括自身和繼承(實(shí)現(xiàn))過來的所有的public方法——Method不支持泛型<>,即后面不接<>
public Method[] getDeclaredMethods();//獲取自身所有的方法(private、public、protected,和訪問權(quán)限無關(guān)),不包括繼承的
public Method[] getMethod(String methodName,
Class
參數(shù):
methodName:表示獲取的方法的名字
parameterTypes:表示獲取的方法的參數(shù)的Class類型
public Method[] getDeclaredMethod(String methodName,
Class
通過java反射調(diào)用方法:
1、先找到方法所在類的字節(jié)碼
2、找到需要被獲取的方法
3、調(diào)用該方法
class User{
public void sayHello(){...}
public void sayHi(String naem){...}
private void sayGoodBye(String name, int age){...}
}
如何使用java反射調(diào)用一個(gè)方法?
在Method類中有一個(gè)方法:
public Object invoke(Object obj, Object... args);//表示調(diào)用當(dāng)前Method所表示的方法
參數(shù):
obj: 表示被調(diào)用方法底層所屬對(duì)象
args: 表示調(diào)用方法時(shí)傳遞的實(shí)際參數(shù)
返回:方法調(diào)用后,底層方法的返回結(jié)果
Eg: public String sayYa(String name){....}
Class
Method mt=clz.getMethod(“sayYa”, String.class);
Object obj=clz.newInstance();
Object ret=mt.invoke(obj, “wili”);//要調(diào)用實(shí)例方法,必須有一個(gè)對(duì)象,方法的底層對(duì)象就是指當(dāng)前Method所在的類的實(shí)例對(duì)象,sayHi方法具有返回值,調(diào)用該方法后的返回結(jié)果使用Object接收
java反射調(diào)用私有方法:
Method mt=clz.getDeclaredMethod(“sayGoodBye”, String.class, int.class);
在調(diào)用私有方法之前,需設(shè)置該方法為可訪問的權(quán)限:——否則會(huì)報(bào)錯(cuò)
mt.setAccessible(true);
mt.invoke(clz.newInstance(), “l(fā)imi”, 17);
java反射調(diào)用靜態(tài)方法
class User{
public static void staticMethod(){
System.out.println(“static mthod invoke.”);
}
}
Eg:
Class
Method staticMethod=clz.getMethod(“staticMthod”);
兩種方式調(diào)用靜態(tài)方法:
1、因?yàn)殪o態(tài)方法屬于所有實(shí)例對(duì)象公共的,可以創(chuàng)建該類的一個(gè)任意對(duì)象,通過該對(duì)象調(diào)用
staticMethod.invoke(clz.newInstance());//staticMethod無參,故參數(shù)列表類型不填
2、如果底層方法是靜態(tài)的,那么可以忽略指定的obj參數(shù),將obj參數(shù)設(shè)置為null即可
staticMethod.invoke(null);
使用java反射調(diào)用可變參數(shù)的方法
class User{
public static int sum(int... ages){
System.out.println(args);//打印結(jié)果可看出:可變參數(shù)底層就是一個(gè)數(shù)組
Int sum=0;
for(int i : args){
Sum+=i;
}
return sum;
}
public static void show(String... args){...}
}
Eg:
Class
Method m=clz.getMethod(“sum”, int[].class);//可變參數(shù)底層就是一個(gè)數(shù)組
M.invoke(null, new int[]{1,2,3});
Method m=clz.getMethod(“show”, String[].class);
M.invoke(null, new String[]{“A”,”B”,”C”});//會(huì)報(bào)錯(cuò),可變參數(shù)是引用類型時(shí),底層會(huì)自動(dòng)解包,上述調(diào)用被解包后變成M.invoke(null,“A”,”B”,”C”);——為了解決該問題,我們?cè)偈褂靡粚訑?shù)組把實(shí)際參數(shù)包裝起來
M.invoke(null, new Object[]{new String[]{“A”,”B”,”C”}});//正確
通用方法:
以后在使用反射調(diào)用invoke方法時(shí),在傳遞實(shí)際參數(shù)的時(shí)候,無論是基本數(shù)據(jù)類型,還是引用類型,或者是可變參數(shù)類型,把實(shí)際參數(shù)都包裝在一維數(shù)組中。
m.invoke(方法的底層對(duì)象,new Object[]{實(shí)際參數(shù)});
Eg:
m.invoke(null, new Object[]{17});//方法參數(shù)為基本類型,且只有一個(gè)參數(shù),解包后變成m.invoke(null,17});
m.invoke(null, new Object[]{“xxx”});//方法參數(shù)為String類型,且只有一個(gè)參數(shù)
m.invoke(null, new Object[]{new int[]{1,2}});//方法參數(shù)為int類型,且為可變參數(shù)或者數(shù)組類型
m.invoke(null, new Object[]{new String[]{“A”,”B”}});//方法參數(shù)為String類型,且為可變參數(shù)或者數(shù)組類型,new String[]{“A”,”B”}為傳遞的實(shí)際參數(shù)
示例:
1、用戶類
package com.lf.entity;
import com.lf.annotation.SetProperty;
import com.lf.annotation.SetTable;
public class UserEntity {
private String userName;
private int userAge;
private final int money = 10000;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
//借錢方法
public int getMoney(){
System.out.println("你借了 " + money + "元!");
return money;
}
//還錢方法,單個(gè)參數(shù)
public void repay(int money){
System.out.println("你還了 " + money + "元!");
}
//還錢方法,多個(gè)參數(shù)
public void repay(String userName,int money){
System.out.println(userName+ " 還了 " + money + "元!");
}
}
2、測(cè)試類
package com.lf.test;
import java.lang.reflect.Method;
import com.lf.entity.UserEntity;
public class Reflection {
//反射調(diào)用方法獲取返回值
//第一種方法,獲取對(duì)象,直接通過對(duì)象調(diào)用方法
//第二種方法,通過方法名獲取方法,執(zhí)行方法
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.lf.entity.UserEntity");
UserEntity userEntity = (UserEntity) userClass.newInstance();
//第一種方法
System.out.println("第一次借錢:");
int money = userEntity.getMoney();
System.out.println("實(shí)際拿到錢為: " + money);
System.out.println("------------------------分割線------------------------");
//第二種方法,(無參的示例:借錢)
System.out.println("第二次借錢:");
Method getMoney = userClass.getMethod("getMoney");//得到方法對(duì)象
Object money2 = getMoney.invoke(userEntity);//調(diào)用借錢方法,得到返回值
System.out.println("實(shí)際拿到錢為:" + money2);
System.out.println("------------------------分割線------------------------");
//第二種方法,(單個(gè)參數(shù)的示例:還錢)
System.out.println("第一次還錢:");
Method repay1 = userClass.getMethod("repay",int.class);//得到方法對(duì)象,有參的方法需要指定參數(shù)類型
repay1.invoke(userEntity,3000);//執(zhí)行還錢方法,有參傳參
System.out.println("------------------------分割線------------------------");
//第二種方法,(單個(gè)參數(shù)的示例:還錢)
System.out.println("第二次還錢:");
Method repay2 = userClass.getMethod("repay", String.class,int.class);//得到方法對(duì)象,有參的方法需要指定參數(shù)類型
repay2.invoke(userEntity,"小飛",5000);//執(zhí)行還錢方法,有參傳參
}
}
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743