vendredi 12 février 2021

Using Class class getMethod() & reflection to find the correct method based on parameter types (with possible upcast)

I'm playing around with Reflection and trying to dynamically call the best fit method based on method name and supplied arguments. I coded up a quick example. Given the method name and an acceptable parameter (or several parameters, eventually) can I identify the correct method to run?

As you can see in this example...

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", "goober", new Double(5.0)); //prints Double
        invoker("Methods", "goober", 5.0);             //prints Double - Not what I wanted
        invoker("Methods", "goober", 5);               //prints NoSuchMethodException - Not what I wanted
        invoker("Methods", "goober", 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); }
    }

}

How can I improve my invoker so that it connect the parameter to the correct method in the same way that java does when I call the method directly?

I'd want the parameter 5.0 to land in the method that receives a primitive double.

I'd want it to realize that the primitive int 5 can land in the method that receives a double.

I'd want it to realize that Integer object can land in the method that receives an Object object.

I'm hesitant to try to code my own system of upcasting because I don't necessarily know how java prioritizes the upcasts (especially when there are multiple parameters). I'd want to ensure that my system identifies the same method that the compiler would identify, and that seems dangerous. I'd rather just ask java which method it would use bind rather than trying to figure it out myself. Does anything like that exist?





Aucun commentaire:

Enregistrer un commentaire