Getting getDeclaredMethods() to match a varargs method

我的未来我决定 提交于 2019-12-19 04:23:30

问题


I want to use getDeclaredMethod() to find a method with this signature:

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

Using this call:

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

But it generates a NoSuchMethodException exception. However, it is possible to invoke the method (assuming you find it some other way):

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

I could list them all, with getDeclaredMethods(), and then try to do the signature matching myself, but that seems like a lot of work.

Should what I want to do be possible? Am I just missing something dumb?


回答1:


The method is callable with any object(s) because it is declared to accept object(s). - But, because it is declared with Object type you won't find via getDeclaredMethod() if you don't search for the exact declared type.

You should be able, though, to iterate over all declared methods and check on their parameter types to see if they are assignable from your given type to find all methods which are callable with your parameters.

Example:

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());
    }
  }
}

However, I have not checked which type(s) Object... actually is assignable from. I assume that it is not Integer but rather Integer[] since the varargs are compiled to arrays.




回答2:


A vararg argument is just syntactic sugar for an array. The signature of the method is

foo(String, Object[]);

and not

foo(String, Integer);



回答3:


The only legal way to find foo method is

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

as for

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

it's quite legal, just as calling foo without reflection

foo("str", new Integer(2));



回答4:


You should treat varargs as an array:

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


来源:https://stackoverflow.com/questions/14022125/getting-getdeclaredmethods-to-match-a-varargs-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!