2

我想getDeclaredMethod()用这个签名找到一个方法:

public void foo(String inArg1, Object... inArgs);

使用此调用:

Class<?>[] argClasses = { String.class, Integer.class };
Method m = clazz.getDeclaredMethod("foo", argClasses);

但它会产生一个NoSuchMethodException异常。但是,可以调用该方法(假设您以其他方式找到它):

Object[] args = { "arg1", new Integer(2) };
m.invoke(instance, args);

我可以用 将它们全部列出getDeclaredMethods(),然后尝试匹配自己的签名,但这似乎需要做很多工作。

我想做的事情应该是可能的吗?我只是错过了一些愚蠢的东西吗?

4

4 回答 4

5

可变参数参数只是数组的语法糖。该方法的签名是

foo(String, Object[]);

并不是

foo(String, Integer);
于 2012-12-24T13:44:07.470 回答
3

找到 foo 方法的唯一合法方法是

Class<?>[] argClasses = { String.class, Object[].class };
Method m = clazz.getDeclaredMethod("foo", argClasses);

至于

Object[] args = { "arg1", new Integer(2) };
m.invoke(instance, args);

这是很合法的,就像调用 foo 没有反射一样

foo("str", new Integer(2));
于 2012-12-24T14:00:02.693 回答
2

您应该将varargs其视为一个数组:

Class<?>[] argClasses = { String.class, Object[].class };
Method m = clazz.getDeclaredMethod("foo", argClasses);
于 2012-12-24T13:46:17.677 回答
2

该方法可以被任何对象调用,因为它被声明为接受对象。- 但是,因为它是用类型声明的,如果你不搜索确切的声明Object类型,你将找不到 via 。getDeclaredMethod()

但是,您应该能够遍历所有声明的方法并检查它们的参数类型以查看它们是否可以您的给定类型分配,以找到所有可使用您的参数调用的方法。

例子:

Class[] signature = {String.class, Integer.class};
Method[] methods = someClass.getDeclaredMethods();

for ( Method m : methods ) {
  Class[] params = m.getParameterTypes();
  if ( params.length == signature.length ) {
    int i;
    for ( i = 0; i < signature.length && params[i].isAssignableFrom( signature[i] ); i++ ) {

    }
    if ( i == signature.length ) {
      System.out.println("Found matching method: " + m.getName());
    }
  }
}

但是,我还没有检查Object...实际上可以分配哪些类型。我认为不是Integer,而是Integer[]因为可变参数被编译为数组。

于 2012-12-24T14:08:41.337 回答