意外的Class.getMethod行为

时间:2010-01-30 21:25:35

标签: java reflection

前一段时间我使用Class.getMethod和autoboxing时有一个similar question,在你自己的查找算法中实现它是有意义的。但真正让我感到困惑的是,以下内容无效:

public class TestClass
{
    public String doSomething(Serializable s)
    {
        return s.toString();
    }

    public static void main(String[] args) throws SecurityException, NoSuchMethodException
    {
        TestClass tc = new TestClass();
        Method m = tc.getClass().getMethod("doSomething", String.class);
    }
}

String.class实现了Serializable接口,我真的希望它包含在查找方法中。 我是否也必须在自己的查找算法中考虑这个问题?

编辑:我确实读过Javadoc,所以让我强调问题的第二部分:如果有的话,你有关于如何快速做到这一点的建议(我已经不得不添加一些自定义匹配和转换算法,我不希望它变得太慢)?

4 个答案:

答案 0 :(得分:5)

根据您的修改,您可以使用Class#isAssignableFrom()。这是一个基本的启动示例(将明显的(运行时)异常处理留在一边):

package com.stackoverflow.q2169497;

import java.io.Serializable;
import java.lang.reflect.Method;

public class Test {

    public String doSomething(Serializable serializable) {
        return serializable.toString();
    }

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        for (Method method : test.getClass().getMethods()) {
            if ("doSomething".equals(method.getName())) {
                if (method.getParameterTypes()[0].isAssignableFrom(String.class)) {
                    System.out.println(method.invoke(test, "foo"));
                }
            }
        }
    }

}

这应该将foo打印到stdout。

答案 1 :(得分:4)

Class.getMethod的javadoc非常明确:

  

parameterTypes参数是   标识的Class对象数组   方法的形式参数类型,   按照声明的顺序。

它不提供子类型的范围。

答案 2 :(得分:1)

getMethod并不是要找到与给定参数类型兼容的方法 - 它意味着找到完全给定参数类型的方法。

您需要调用getMethods()来查找所有方法,然后按名称和参数数量进行过滤,然后确定哪些方法实际适用。

答案 3 :(得分:0)

为什么要用getMethod致电String.class?方法签名完全映射。按照与调用它们相同的标准查找方法没有任何意义。