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