我想使用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()
列出所有内容,然后尝试自己进行签名匹配,但这看起来很多工作。
我想做什么可能吗?我只是缺少一些愚蠢的东西吗?
答案 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被编译为数组。