[英]Method.invoke throws java.lang.IllegalArgumentException: wrong number of arguments
[英]Using method.invoke Exception in thread “main” java.lang.IllegalArgumentException: wrong number of arguments
我試圖調用一個方法並返回值; 但是,我得到了一個IllegalArgumentException:錯誤的參數數量
這是示例代碼:
public class MyObjAnnoParser {
public void parse(Class clazz, Object obj) throws ClassNotFoundException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException{
WatchLogAnno wlAnno= method.getAnnotation(WatchLogAnno.class);
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(WatchLogAnno.class)) {
String info = wlAnno.parentClass();
Class cls = Class.forName(info);
//error occurs here -- not sure what it means by wrong number
//the obj is wrapped as an Object array as can be seen....
Object objVal= method.invoke(cls.newInstance(), new Object[]{obj});
System.out.println(objVal);
}
}
}
}
注釋類:
@Target(ElementType.METHOD )
@Retention(RetentionPolicy.RUNTIME)
public @interface WatchLogAnno {
String parentClass() default "";
}
MyObj類別:
public class MyObj {
private String summary;
@WatchLogAnno(parentClass = "com.stuff.MyObj")
public String getSummary(){
return summary;
}
public void setSummary(String summary){
this.summary = summary;
}
}
測試調用解析器的類:
public class MyObjAnnoParserTest {
public static void main(String [] args) throws Exception {
MyObjAnnoParser parser = new MyObjAnnoParser ();
parser.parse(Annotated.class);
MyObj myObj = new MyObj();
myObj.setSummary("Testing an entry for this piece");
parser.parse(myObj.class, myObj );
}
}
因此,正如我在注釋中上面列出的那樣,當我進入invoke.method調用時,它將引發IllegalArgumentException...。
我確信這是一個簡單的錯誤...感謝您的幫助...謝謝!
在行中
Object objVal= method.invoke(cls.newInstance(), new Object[]{obj});
您嘗試使用簽名調用方法
Object method(Object o)
但是你的clas有簽名
String getSummary()
因此,反射找不到任何方法。
您也可以在類中創建一個新對象,而不使用提供的對象。
嘗試使用以下方式調用反射
Object objVal = method.invoke(obj, new Object[]{});
沒有任何參數。
package test;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class datadriven_jnuit {
private int var1;
private int var2;
public void datadriven_junit(int a, int b)
{
this.var1 = a;
this.var2 = b;
}
@Parameterized.Parameters
public static List<Object []> data()
{
return Arrays.asList (new Object[][] { {543,11},{65,47}} );
}
@Test
public void testcase()
{
System.out.println( var1);
System.out.println(var2);
}
}
方法
@WatchLogAnno(parentClass = "com.stuff.MyObj")
public String getSummary(){
return summary;
}
不帶任何參數(除隱this
對象)。 但是,調用該方法時,您將傳遞一個:
method.invoke(cls.newInstance(), new Object[]{obj});
要么做
method.invoke(cls.newInstance(), new Object[0]);
或定義被叫方以采用參數:
@WatchLogAnno(parentClass = "com.stuff.MyObj")
public String getSummary(Object mustBeDeclaredEvenIfNotUsed){
return summary;
}
第三種可能性是, 使用反射檢查要調用的方法預期有多少參數,並相應地調整參數:
// UNTESTED!
final Class<?>[] expectedParams = method.getParameterTypes();
Object[] actualValues;
if (expectedParams.length == 0) actualValues = new Object[0];
else if (expectedParams.length == 1) actualValues = new Object[] { obj };
else
throw new UnsupportedOperationException("callee has wrong method signature");
如果走這條路線,那么檢查聲明的參數類型是否與實際值兼容可能也是一個好主意:
if (!expectedParams[0].isAssignableFrom(obj))
throw new UnsupportedOperationException("callee's declared parameter type does not match the argument value");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.