Joby Wilson Mathews
Joby Wilson Mathews

Reputation: 11116

Get a method of class with parameter of primitive type using Reflection

I am trying to get a method of a class using reflection where argument of that method is sometimes a primitive type or any Object.

Example:

public class A {

public void display(short a){
    System.out.println(a);
    }

}

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.rexample.model.A;

public class ReflectionExample {

    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        ReflectionExample example=new ReflectionExample();
        example.print();
    }

    public void print() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        String nameOfTheMethod="display";//Assume name of the method is display
        short v=10;//Assume primitive type is short
        Object value=v;
        Method method=A.class.getDeclaredMethod(nameOfTheMethod,value.getClass());
        method.invoke(new A(),value);
    }

}

And i am getting the error:

Exception in thread "main" java.lang.NoSuchMethodException: com.rexample.model.A.display(java.lang.Short)
    at java.lang.Class.getDeclaredMethod(Class.java:2130)
    at com.rexample.test.ReflectionExample.print(ReflectionExample.java:34)
    at com.rexample.test.ReflectionExample.main(ReflectionExample.java:27)

Above code is just a small example of a larger program that i am currently building where i cannot able to get method of parameter type short or any other primitive type.

I cannot able to directly use short.class or Short.TYPE in my code , Since i am trying to do in a more generic way.

Is there any way to solve my issue for parameter of primitive type and of any objects?

Upvotes: 1

Views: 1614

Answers (1)

davidxxx
davidxxx

Reputation: 131346

Actually you assign the value (object or primitive) to a declared type Object :

Object value=v;

As v is an Object it is ok but as it is a primitive it is a problem as at runtime the JVM boxes it to the corresponding wrapper class.
So here you lose the original information that v is a primitive :

method=A.class.getDeclaredMethod(nameOfTheMethod,value.getClass());

The only way to handle it correctly is to distinguish primitives and objects.
You could overload getType() to handle both :

public Class<?> getType(Object o) {
    return o.getClass();
}

public Class<?> getType(short s) {
    return short.class;
}

public Class<?> getType(int i) {
    return int.class;
} 

// add overloads with other primitive types if required

Here is an example with two invocations by reflection : one with a primitive param and the other with an object param.

A class

public class A {

    public void display(short a) {
        System.out.println("primitive " + a);
    }

    public void display(Short a) {
        System.out.println("Wrapper " + a);
    }
}

ReflectionExample class

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionExample {

    public static void main(String[] args)
            throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        ReflectionExample example = new ReflectionExample();
        example.print();
    }

    public void print() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        String nameOfTheMethod = "display";

        // primitive param call
        short s = 10;
        Method method = A.class.getDeclaredMethod(nameOfTheMethod, getType(s)); // invoke getType(short s)
        method.invoke(new A(), s); 

        // object param call
        Short sWrapper = 10;// Assume primitive type is short
        method = A.class.getDeclaredMethod(nameOfTheMethod, getType(sWrapper)); // invoke getType(Object o)
        method.invoke(new A(), sWrapper);
    }

    public Class<?> getType(short s) {
        return short.class;
    }

    public Class<?> getType(int i) {
        return int.class;
    }
    ... //

    public Class<?> getType(Object o) {
        return o.getClass();
    }

}

Output :

primitive 10

Wrapper 10

Upvotes: 2

Related Questions