Supposons que vous ayez cette classe
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)
et setO(Integer i)
sont deux méthodes différentes, de sorte que vous ne pouvez pas avoir un seul d'entre eux dans votre classe et compter sur autoboxing pour obtenir l'objet de la méthode par Class#getMethod(Class<?>...)
et passer un ou l'autre type d'argument.
@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));
}
sera à la fois imprimer
set int
set int
et
set Integer
set Integer
Ici Autoboxing travaux sur invokation.
Mais dans votre cas, vous extrayez le type de l'argument d'une valeur qui est stockée sous Object
. Dans ce cas, les types primitifs sont autoboxés dans leurs types de wrapper respectifs, donc vous ne trouvez pas une méthode qui correspond à int.class
comme 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));
}
Ici la sortie est:
false
set Integer
false
set Integer
Comme vous le voyez, pas primitives et seule la méthode avec Integer.class
se trouve et a appelé. Si vous l'enlevez, vous obtiendrez NoSuchMethodException
. Donc, pour résoudre votre problème, changez la méthode que vous essayez d'invoquer via la réflexion pour prendre un type de wrapper ou, mieux encore, passez les types d'arguments corrects au lieu de les déduire de certaines valeurs.
Enfin, NoSuchMethodException
est également levé lorsque la méthode n'est pas accessible, c'est-à-dire pas public
, assurez-vous que la méthode est publique.