2

如果我运行以下程序:

class Runit{
    public static void main(String[] argsWut) throws Exception {
        String arg = "what?";
        Class[] parameters = { new Object().getClass() };
        Object[] args = { arg };
        System.out.println("".getClass().getMethod("equals",parameters).invoke("what?",args));
    }
};

我在命令行上得到以下信息:

true

另一方面,如果我稍微修改一下参数行:

class Runit{
    public static void main(String[] argsWut) throws Exception {
        String arg = "what?";
        Class[] parameters = { arg.getClass() }; // changed a little here so it's a bit more dynamic --
        Object[] args = { arg };
        System.out.println("".getClass().getMethod("equals",parameters).invoke("what?",args));
    }
};

我得到:

Exception in thread "main" java.lang.NoSuchMethodException: java.lang.String.equals(java.lang.String)
    at java.lang.Class.getMethod(Class.java:1605)
    at test.Runit.main(Runit.java:7)

从这个例子来看,在我看来,该getMethod方法似乎只适用于精确的参数。有没有办法获得某种形式的“最合适”的方法?例如,如果存在完全匹配,它将返回该方法,但如果不存在完全匹配,它可以返回任何可以接受我给定参数的方法。

4

3 回答 3

5

您可能对 Apache Commons Lang MethodUtils 类有更好的运气,该类有一个方法“invokeMethod”,该方法使用方法的目标参数来缩小适当的类型(即,您不必告诉它参数类型)。

这似乎有效:

 System.out.println(MethodUtils.invokeMethod("what?", "equals", new Object[] {"what?"}));

有关更多详细信息,请参阅 javadocs:http ://commons.apache.org/lang/api/org/apache/commons/lang3/reflect/MethodUtils.html#invokeMethod(java.lang.Object,%20java.lang.String,% 20java.lang.Object ...)

于 2012-06-19T23:09:13.690 回答
5

您可能对Commons BeanUtilsApache 库感兴趣,特别是这种方法: http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/MethodUtils.html#getMatchingAccessibleMethod%28java.lang.Class, %20java.lang.String,%20java.lang.Class%5b%5d%29

希望这可以帮助

于 2012-06-19T23:09:18.860 回答
3

文档中getMethod()

在 C 类中找到匹配的方法:如果 C 声明了一个具有指定名称和完全相同的形参类型的公共方法,则该方法被反映。如果在 C 中发现了多个这样的方法,并且其中一个方法的返回类型比其他任何方法都更具体,则反映该方法;否则任意选择其中一种方法。

强调我的。)

您要求的是让反射为您执行重载解决方案。显然它不会。如果您确实需要此功能,您可以 1) 放弃使用反射并直接调用该方法,或者 2) 如果无法实现,请在 Java 中查找重载解析规则(您可以从此处开始),用于getMethods()确定可用的方法,然后手动执行重载决议。欢乐时光,我知道。

编辑:正如其他 回答者指出的那样,有人已经花时间为你做这件事。凉爽的!

于 2012-06-19T23:05:13.353 回答