Suppose you have this class
class ReflectTest {
Object o = null;
public void setO(int i) {
System.out.println("set int");
o = i;
}
public void setO(Integer i) {
System.out.println("set Integer");
o = i;
}
}
setO(int i)
and setO(Integer i)
are two different methods, so you cannot have only one of them in your class and rely on autoboxing to get the method object via Class#getMethod(Class<?>...)
and passing one or the other argument type.
@Test
public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method method = ReflectTest.class.getMethod("setO", int.class);
method.invoke(new ReflectTest(), 3);
method.invoke(new ReflectTest(), Integer.valueOf(3));
method = ReflectTest.class.getMethod("setO", Integer.class);
method.invoke(new ReflectTest(), 3);
method.invoke(new ReflectTest(), Integer.valueOf(3));
}
will both print
set int
set int
and
set Integer
set Integer
Here autoboxing works on invokation.
But in you case you extract the type of the argument from a value which is stored as Object
. In this case primitive types are autoboxed into theire respective wrapper types, hence you do not find a method which corresponds to int.class
as argument.
@Test
public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
invoke(new ReflectTest(), "setO", 3);
invoke(new ReflectTest(), "setO", Integer.valueOf(3));
}
private void invoke(Object instance, String methodeName, Object argValue) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
System.out.println(argValue.getClass().isPrimitive());
Method method = ReflectTest.class.getMethod("setO", argValue.getClass());
method.invoke(new ReflectTest(), argValue);
method.invoke(new ReflectTest(), Integer.valueOf(3));
}
Here the output is:
false
set Integer
false
set Integer
As you see, no primitives and only the method with Integer.class
is found and called. If you remove it you will get NoSuchMethodException
.
So to solve your problem change the method your are trying to invoke via reflection to take a wrapper type or better yet, pass the correct argument types instead of deriving them from some values.
Finally, NoSuchMethodException
is also thrown when the method is not accessible i.e. not public
, make sure the method is public.