获取getDeclaredMethods()以匹配varargs方法

时间:2012-12-24 13:39:50

标签: java reflection variadic-functions

我想使用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 个答案:

答案 0 :(得分:5)

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

foo(String, Object[]);

而不是

foo(String, Integer);

答案 1 :(得分: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));

答案 2 :(得分:2)

您应该将varargs视为数组:

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

答案 3 :(得分:2)

该方法可调用包含任何对象,因为声明接受对象。 - 但是,因为它是声明Object类型,如果您没有搜索确切的声明的类型,则无法通过getDeclaredMethod()找到

但是,您应该可以迭代所有已声明的方法,并检查他们的parameter types,看看它们是否为assignable from您的给定类型,以查找可调用的所有方法带有你的参数。

示例:

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[],因为varargs被编译为数组。