Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:运行时方法解析_Java_Reflection_Overload Resolution - Fatal编程技术网

Java:运行时方法解析

Java:运行时方法解析,java,reflection,overload-resolution,Java,Reflection,Overload Resolution,我正在通过解释器进行一些代码的动态调用,并且我正在进入方法解析的棘手难看的领域,如中所讨论的 选择方法的“简单”方法是当您知道所有参数的确切类型时,此时您可以使用。也许您必须检查方法的可访问性和类的超类/超接口 但这不包括以下任何一种情况,所以它是无用的: 装箱/取消装箱原语 亚型 瓦拉格斯 null参数(可以是任何类型,除非解释器另行知道;在编译时,通过将null强制转换到类/接口来消除任何歧义) 原语类型转换(不是Java的一部分,但在语言环境中是允许的——例如Rhino Javascri

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

选择方法的“简单”方法是当您知道所有参数的确切类型时,此时您可以使用。也许您必须检查方法的可访问性和类的超类/超接口

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

  • 装箱/取消装箱原语
  • 亚型
  • 瓦拉格斯
  • null参数(可以是任何类型,除非解释器另行知道;在编译时,通过将null强制转换到类/接口来消除任何歧义)
  • 原语类型转换(不是Java的一部分,但在语言环境中是允许的——例如Rhino Javascript,其中所有数字都是浮点型的,因此Java代码可能采用
    int
    ,但调用者传入的数字可以是
    int
    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);
    }
}
package com.example.test.reflect;
导入java.lang.reflect.Method;
公共类方法解析测试{
公共void计算(int i){/*实现…*/}
公共void计算(长l){/*实现…*/}
公共void计算(对象obj){/*实现…*/}
公共void计算(字符串…字符串){/*实现…*/}
公共静态void main(字符串[]args){
类别cl=MethodResolutionTest.Class;
/*这些成功*/
findAndPrintMethod(cl,“计算”,int.class);
findAndPrintMethod(cl,“计算”,Long.class);
findAndPrintMethod(cl,“计算”,Object.class);
findAndPrintMethod(cl,“计算”,字符串[]。类);
/*这些失败了*/
findAndPrintMethod(cl,“计算”,Integer.class);
findAndPrintMethod(cl,“计算”,long.class);
FindPrintMethod(cl,“计算”,MethodResolutionTest.class);
findAndPrintMethod(cl,“计算”,String.class,String.class);
}
私有静态void findAndPrintMethod(类objectClass,
字符串方法名称,类…参数类型)
{
试一试{
Method=findMethod(对象类、方法名、,
参数类型);
System.out.println(method.toString());
}
捕获(安全异常e){
e、 printStackTrace();
}
捕获(无此方法例外){
e、 printStackTrace();
}
}
私有静态方法findMethod(类objectClass,
字符串方法名,类[]参数类型)
抛出SecurityException,NoSuchMethodException
{
返回objectClass.getDeclaredMethod(方法名,参数类型);
}
}

我在MVEL和属性方面取得了一些成功,但我记不起它是否能够分派方法调用


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

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


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

您可能需要阅读并签出。它应该可以为您完成大部分繁重的工作。

番石榴上的一位用户建议我查看


不幸的是,它也不能处理重载解析,至少目前不能。

@Jonathon:我知道isAssignableFrom。我在处理子类型和装箱/拆箱时得到了一些自制的东西。然后我开始进入瓦拉格斯,它变得很糟糕,我想,“等等,我为什么要这么做?”所以我特别寻找一个已经存在的图书馆。(或者至少是一组好的预先存在的测试用例)否则我可以自己做,但这是一个很大的痛苦。除非你找到一个可爱的库,否则我认为你做的任何事情都会很难看,很难阅读。是的,我知道。如何吸引谷歌、甲骨文、IBM、Apache或其他公司的Java半神来制作一个好的非病毒开源库来实现这一点?这是Java反射的缺失部分,IMHO。我可以想出一些适合我自己的方法,但我认为无论是在正确性/文档记录/可维护性方面都远远不够完美。请注意,在
getMatchingAccessibleMethod
中,基本匹配是单向的-参数
Long。class
将匹配
foo(Long)
但是
Long.TYPE
foo(Long)
+1:@Bengt:发现Apache有一些工具,这让我松了一口气,也许不是我想要的,但至少是一些东西。嗯,出于各种原因,我“卡在”Java上,最大的一个原因是可维护性(添加不同的语言明显限制了我从其他开发人员那里获得帮助的能力)啊!太有希望了,但它有点不同——它解析泛型类型,但对方法解析没有任何作用。但至少这是一个开始,我敢打赌我可以诱使作者扩展它。