Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i know if something is primitive type after autoboxing?

I know there are a lot of quesitons about reflection and primitive types already, but i didn't really get the exact information i searched. My Problem is following: I want to invoke methods (through reflection) completely dynamical, that means i want to invoke them even if i dont exactly know the types of the parameters.

public Object invoke(Object objectContainingMethod,String methodName, Object...params) {
    Object result = null;
    int length = params.length;
    Class<?>[] paramTypes = new Class<?>[length];

    for(int i=0; i<length; i++) {
        paramTypes[i] = params[i].getClass();
    }

    try {
        Method method = objectContainingMethod.getClass().getMethod(methodName, paramTypes);
        // not hard coded like getMethod(methodName, String.class, int.class, double.class);
        result = method.invoke(objectContainingMethod, params);
    } catch (NoSuchMethodException | SecurityException | 
             IllegalAccessException | IllegalArgumentException | 
             InvocationTargetException e) { 
        e.printStackTrace();
    }

    return result;
}

(Didn't optimized anything yet so pls don't hate^^) The problem is, the parameter for the method need to be converted in Object but when i do this you can't really detect anymore if it is a primitive type because of auto boxing. Which happens when i try to call the Method "charAt" from the class String with an int parameter:

String instance = "hello";
Object result = invoke(instance,"charAt",0);

which obviously results in:

java.lang.NoSuchMethodException: java.lang.String.charAt(java.lang.Integer)
at java.lang.Class.getMethod(Unknown Source)...

He searched for Integer instead of int because of auto-boxing. So is there a work around for what i'm trying to do here? I know how to detect primitive types, but not when they are auto-boxed to their wrapper types. Any help is greatly appreciated.

like image 766
Alastorftw Avatar asked Oct 03 '22 00:10

Alastorftw


1 Answers

You'll have to pass a Class array as an argument in to your custom invoke method that has the explicit types to search for in the method signature instead of trying to determine types from the parameters directly. This is exactly why Class.getMethod(String, Class[]) requires the types instead of inferring from parameters.

Change your signature to something like this. Use the class array directly, instead of inferring types. Alternatively you could us a Collection instead of an array, this is merely for example.

public Object invoke(Object objectContainingMethod,String methodName, Class<?>[] types, Object...params)
like image 69
Dev Avatar answered Oct 10 '22 15:10

Dev