工作需要用到類方法的反射調(diào)用,網(wǎng)上找到這樣一段代碼:
public static Object invokeMethod(Object object, String methodName, Class[] parameterTypes, Object... parameters) {
//根據(jù) 對象、方法名和對應(yīng)的方法參數(shù) 通過反射 調(diào)用上面的方法獲取 Method 對象
Method method = getDeclaredMethod(object, methodName, parameterTypes);
//抑制Java對方法進(jìn)行檢查,主要是針對私有方法而言
method.setAccessible(true) ;
try {
if(null != method) {
//調(diào)用object 的 method 所代表的方法,其方法的參數(shù)是 parameters
return method.invoke(object, parameters) ;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
哎,既然后面?zhèn)魅肓?parameters,那么 parameterTypes 直接 parameters.getClass() 就好了,何必再傳;
于是稍加修改,該方法變成這個樣子:
public static Object invokeMethod(Object object, String methodName, Object... parameters) {
//根據(jù) 對象、方法名和對應(yīng)的方法參數(shù) 通過反射 調(diào)用上面的方法獲取 Method 對象
Class[] parameterTypes = new Class[parameters.length];
for(int i = 0; i < parameters.length; i++){
parameterTypes[i] = parameters[i].getClass();
}
Method method = getDeclaredMethod(object, methodName, parameterTypes);
//抑制Java對方法進(jìn)行檢查,主要是針對私有方法而言
method.setAccessible(true) ;
try {
if(null != method) {
//調(diào)用object 的 method 所代表的方法,其方法的參數(shù)是 parameters
return method.invoke(object, parameters) ;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
嗯,不禁為自己的機智點贊;
于是加入工程,跑起來,哎,怎么反射找不到方法;
仔細(xì)觀察,調(diào)用時的代碼是 ClassReflectionUtils.invokeMethod(obj, "func", 123);
調(diào)試步進(jìn),觀察 paramters,發(fā)現(xiàn)變成了 Integer 類型;

原來立即數(shù)會被強轉(zhuǎn)為這種“高級立即數(shù)類”;
那么再測試一下:
public static void fun(Object... args){
for(Object object : args){
Class xx = object.getClass();
System.out.println(xx);
}
return;
}
public static void main(String[] args) {
int m = 1;
double n = 2.3;
fun(m, n);
}
得到了如下輸出:

嗯,看來確實會被強轉(zhuǎn),那么 invokeMethod 的 parameterTypes 參數(shù)是不可省略了,再恢復(fù)之前的 invokeMethod ,跑起來,成功了。
其實省略該參數(shù)還有一個問題,當(dāng) parameters.getClass() 為子類,而指定 method 中需要的父類時,findMethod 應(yīng)該也找不到方法,這里感興趣的讀者可以自行測試一下。