15

我正在通过解释器对代码进行一些动态调用,并且我正在进入JLS 第 15.12 节中讨论的方法解析的棘手难看领域。

选择方法的“简单”方法是当您知道所有参数的确切类型时,您可以使用Class.getDeclaredMethod(String name, Class[] parameterTypes). 也许您必须检查方法可访问性和类的超类/超接口。

但这不包括以下任何一种情况,所以它有点没用:

  • 装箱/拆箱原语
  • 亚型
  • 可变参数
  • 一个空参数(可以是任何类型,除非解释器另有说明;在编译时,通过将空转换为类/接口可以消除任何歧义)
  • 原始类型转换(不是 Java 的一部分,但在语言上下文中是允许的 - 例如 Rhino Javascript,其中所有数字都是浮点数,因此 Java 代码可能采用 anint但调用者传入一个数字,即 anint或 a double

(有关前三个的快速示例,请参见下文)

所以现在我必须编写自己的方法解析库......

是否有任何知名的框架库可以帮助实现这一点?

package com.example.test.reflect;

import java.lang.reflect.Method;

public class MethodResolutionTest {
    public void compute(int i)              { /* implementation... */ }
    public void compute(Long l)             { /* implementation... */ }
    public void compute(Object obj)         { /* implementation... */ }
    public void compute(String... strings)  { /* implementation... */ }

    public static void main(String[] args) {
        Class<?> cl = MethodResolutionTest.class;

        /* these succeed */
        findAndPrintMethod(cl, "compute", int.class);
        findAndPrintMethod(cl, "compute", Long.class);
        findAndPrintMethod(cl, "compute", Object.class);
        findAndPrintMethod(cl, "compute", String[].class);

        /* these fail */
        findAndPrintMethod(cl, "compute", Integer.class);
        findAndPrintMethod(cl, "compute", long.class);
        findAndPrintMethod(cl, "compute", MethodResolutionTest.class);
        findAndPrintMethod(cl, "compute", String.class, String.class);
    }
    private static void findAndPrintMethod(Class<?> objectClass, 
            String methodName, Class<?>... parameterTypes) 
    {
        try {
            Method method = findMethod(objectClass, methodName, 
                   parameterTypes);
            System.out.println(method.toString());
        }
        catch (SecurityException e) {
            e.printStackTrace();
        }
        catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    private static Method findMethod(Class<?> objectClass, 
            String methodName, Class<?>[] parameterTypes) 
        throws SecurityException, NoSuchMethodException 
    {
        return objectClass.getDeclaredMethod(methodName, parameterTypes);
    }
}
4

4 回答 4

3

您可能想阅读这篇博文并查看ClassMate。它应该为您完成大部分蹩脚的工作。

于 2011-05-17T09:52:21.903 回答
2

Commons beanutils 有这个查找匹配方法的功能: getMatchingAccessibleMethod

它适用于原始类型,但正如文档所说,它有点不确定。

于 2011-05-16T22:53:36.643 回答
0

guava-discuss 上的一位用户推荐我查看Mirror 库

不幸的是,它也不处理重载决议,至少目前没有。

于 2011-05-20T16:35:23.520 回答
-1

我在 MVEL 和属性方面取得了一些成功,但我不记得它是否可以调度方法调用。

但是,您可能正在寻找完全不同的语言。鉴于问题的性质,我建议看一下 Groovy,它与 Java 的集成非常干净。

于 2011-05-16T22:13:07.560 回答