0

我正在尝试调用一个方法并返回值;但是,我得到一个 IllegalArgumentException: wrong number of arguments

这是示例代码:

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...。

我确信这是一个简单的错误...感谢您的帮助...谢谢!

4

3 回答 3

0

在行

Object objVal= method.invoke(cls.newInstance(), new Object[]{obj});

您尝试使用签名调用方法

Object method(Object o)

但你的班级有签名

String getSummary()

因此反射找不到任何方法。

您还可以为您的类创建一个新对象,而不是使用提供的对象。

尝试调用反射

Object objVal = method.invoke(obj, new Object[]{});

没有任何参数。

于 2013-06-06T12:43:05.800 回答
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);
    }

}
于 2015-05-19T06:34:57.807 回答
-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;
}

作为第三种可能性,使用反射检查被调用方法需要多少参数,并相应地调整参数:

 // 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");
于 2013-06-06T12:43:57.587 回答