Java:运行时方法解析

时间:2011-05-16 17:34:00

标签: java reflection overload-resolution

我正在通过解释器进行一些动态的代码调用,我正在进入JLS section 15.12中所讨论的方法解决的粘性丑陋区域。

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

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

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

(参见下面的前三个快速示例)

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

是否有任何众所周知的框架库可以帮助解决这个问题?

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 个答案:

答案 0 :(得分:3)

您可能需要阅读this blog post并查看ClassMate。它应该为你做大部分蹩脚的工作。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

番石榴之一的讨论用户建议我查看Mirror library

不幸的是,它不会处理重载分辨率,至少目前还没有。

答案 3 :(得分:-1)

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

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