使用 Class class getMethod() & 反射根据参数类型找到正确的方法可能向上转换

问题描述

我正在玩反射并尝试根据方法名称和提供的参数动态调用最适合的方法。我编写了一个快速示例。给定方法名称和可接受的参数(或多个参数,最终),我可以确定要运行的正确方法吗?

正如你在这个例子中看到的......

public class Methods
{
    public static void goober(Object o) {
        System.out.println("Object");
    }

    public static void goober(Double d) {
        System.out.println("Double");
    }

    public static void goober(double d) {
        System.out.println("double");
    }
}

import java.lang.reflect.Method;
public class MethodIDTester
{
    public static void main(String[] args) {
        Methods.goober(new Object());    //prints Object                
        Methods.goober(new Double(5.0)); //prints Double        
        Methods.goober(5.0);             //prints double        
        Methods.goober(5);               //prints double        
        Methods.goober(new Integer(5));  //prints Object   
        System.out.println();

        invoker("Methods","goober",new Object());    //prints Object             
        invoker("Methods",new Double(5.0)); //prints Double
        invoker("Methods",5.0);             //prints Double - Not what I wanted
        invoker("Methods",5);               //prints NoSuchMethodException - Not what I wanted
        invoker("Methods",new Integer(5));  //prints NoSuchMethodException - Not what I wanted
    }

    public static void invoker(String cName,String mName,Object param) {
        try {
            Class<?> c = Class.forName(cName);        
            Method m = c.getmethod(mName,param.getClass());
            m.invoke(c,param);
        } catch (Exception e) { System.out.println(e); }
    }

}

如何改进我的调用程序,使其以与直接调用方法时 java 相同的方式将参数连接到正确的方法

我希望参数 5.0 位于接收原始双精度值的方法中。

我希望它意识到原始 int 5 可以落在接收双精度值的方法中。

我希望它意识到 Integer 对象可以在接收 Object 对象的方法中着陆。

我很犹豫要不要尝试编写我自己的向上转换系统,因为我不一定知道 java 如何确定向上转换的优先级(尤其是当有多个参数时)。我想确保我的系统识别与编译器识别的方法相同的方法,这似乎很危险。我宁愿只问 java 它会使用哪种方法 bind 而不是试图自己弄清楚。有这样的东西吗?

解决方法

反射查找与方法的精确声明匹配,这就是为什么某些查找返回 NoSuchMethodException 的原因。如果找不到方法,您可以尝试查看超类。

GroupBy

对于调用者调用,double 值被自动装箱为 Double,因此处理 Double / double 情况的唯一方法是将调用者更改为提供 double.class。

要解决这两个问题,您可以添加 Method m = c.getMethod(mName,param.getClass()); 来查找类,例如:

invoker()

那么:

public static void invoker(String cName,String mName,Object param) {
    invoker(cName,mName,param.getClass(),param);
}
public static void invoker(String cName,Class<?> argC,Object param)    {
    try {
        Class<?> c = Class.forName(cName);
        System.out.println("invoker "+cName+"."+mName+"("+argC.getName()+") with param "+param);
        Method m = c.getMethod(mName,argC);
        m.invoke(c,param);
    }
    catch (NoSuchMethodException e) {
        Class<?> sup = argC.getSuperclass();
        if (sup != null)
            invoker(cName,sup,param);
    }
    catch (Exception e) {
        System.out.println(e);
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...