簡體   English   中英

在線程“主”中使用method.invoke異常java.lang.IllegalArgumentException:參數數量錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM