我试图调用一个方法并返回该值;但是,我得到一个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 ....
我确信这是一个简单的错误......我感谢任何帮助......谢谢!
答案 0 :(得分:0)
在第
行Object objVal= method.invoke(cls.newInstance(), new Object[]{obj});
您尝试使用签名
调用方法Object method(Object o)
但你的clas有签名
String getSummary()
因此反射找不到任何方法。
您也可以在课堂上创建一个新对象,而不是使用提供的对象。
尝试使用
调用反射Object objVal = method.invoke(obj, new Object[]{});
没有任何参数。
答案 1 :(得分:0)
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);
}
}
答案 2 :(得分:-1)
方法
@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;
}
作为第三种可能性,use reflection要检查,要调用的方法有多少参数,并相应地调整参数:
// 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");