【问题标题】:Wrong number of arguments error when invoking a method调用方法时错误数量的参数错误
【发布时间】:2020-05-31 04:01:00
【问题描述】:

我有一个类 AClass 和一个方法 someMethod,它获取一个 Object 数组作为参数。

public class AClass {
    public void someMethod(Object[] parameters) {
    }
}

在main中,当我尝试在我创建的对象上调用此方法并将对象数组作为此方法的参数时

Object[] parameters; // lets say this object array is null
Class class = Class.forName("AClass");
Object anObject = class.newInstance();

Method someMethod = class.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, parameters);

我得到“错误数量的参数错误”。 我错过了什么?

【问题讨论】:

标签: java reflection illegalargumentexception


【解决方案1】:

没关系。

Object[] parameters = {new Object()}; // lets say this object array is null
Class clas = Class.forName("AClass");
Object anObject = clas.newInstance();

Object[] param = {parameters};

Method someMethod = clas.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, param);

注意invoke方法的第二个参数。本身就是Object[],你方法的参数类型也是Object[]

【讨论】:

  • 这令人困惑; P 是什么?你传入了一个Object[],其中包含一个Object[],其中包含一个Object,它没有任何空值。
  • 它有效,但我不明白为什么我们必须写这行:Object[] param ={parameters};
  • 因为 someMethod 的签名是 method.invoke(Object obj, Object... args)。其实someMethod只有一个参数是Object[],所以应该传参数[Object[]]
【解决方案2】:

稍微扩展一下 orien 和 bioobiaoqi 的意思。 . .

这里可能让您感到困惑的是Method.invoke(Object, Object...) 通常可以只接受“内联”参数,可以这么说;当编译器看到类似someMethod.invoke(someObject, arg1, arg2) 的内容时,它会隐式创建一个数组new Object[]{arg1, arg2},然后将该数组传递给Method.invokeMethod.invoke 然后将该数组的元素作为参数传递给您正在调用的方法。到目前为止,一切顺利。

但是当编译器看到像someMethod.invoke(someObject, someArray) 这样的东西时,它假定你已经将参数打包到一个数组中;所以它不会再次重新包装它们。那么Method.invoke 将尝试将someArrayelements 作为参数传递给您正在调用的方法,而不是将someArray itself 作为参数传递。

(这始终是 ... 符号的工作方式;它接受 either 包含适当类型元素的数组,零个或多个适当类型的参数.)

因此,正如 orien 和 biaobiaoqi 所说,您需要将 parameters 重新包装到一个额外的数组 new Object[] {parameters} 中,以便 parameters 本身最终被传递到您的方法中。

这有意义吗?

【讨论】:

  • 最好的解释谢谢。
【解决方案3】:

Method.invoke 方法接受对象来接收方法调用和方法的参数数组。由于您的方法采用一个参数,因此给定数组的大小必须为 1

尝试创建一个大小为1的新数组:

someMethod.invoke(anObject, new Object[] {parameters});

请注意,此数组中的一个值可以是null。这将模拟anObject.someMethod(null)

【讨论】:

    【解决方案4】:

    invoke的参数是Object的数组;你的参数应该是一个Object[]包含你传递给someMethodObject[]

    您不需要创建立即数组来执行此操作,因为invoke 签名是invoke(Object, Object...),但在您的情况下,您尝试传入一个 数组。如果要传入null:

    Object[] parameters = { null };
    ...
    someMethod.invoke(anObject, parameters);
    

    然而,最终,其他答案是正确的:您需要传入一个Object[],其中包含每个方法参数的条目。

    【讨论】:

      【解决方案5】:

      试试这个:

          someMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
      

      我是通过使用 dp4j 自动生成您的代码的反射 API 版本得到的:

      $ javac -cp dp4j-1.2-jar-with-dependencies.jar -Averbose=true AClass.java
      AClass.java:10: Note: 
      import com.dp4j.*;
      
      public class AClass {
      
          public AClass() {
              super();
          }
      
          public void someMethod(Object[] parameters) {
          }
      
          @Reflect(all = true)
          public static void main(String... args) throws ... {
              Object[] parameters = null;
              ...
              AClass anObject;
              anObject = (.AClass)aClassConstructor.newInstance();
              java.lang.reflect.Method someMethodWithArrayMethod = null;
              someMethodWithArrayMethod = Class.forName("AClass").getDeclaredMethod("someMethod", .java.lang.Object[].class);
              someMethodWithArrayMethod.setAccessible(true);
              someMethodWithArrayMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多