2015-08-01 1 views
1

J'utilise la méthode getMethod (String name, Class [] types) pour obtenir une méthode mais une méthode n'est pas trouvée lorsqu'il y a un paramètre int. Je pense que je comprends cela parce que dans mon tableau de classe j'ai la classe java.lang.Integer (le wrapper) au lieu de int. Je reçois cette classe en utilisant un Object.getClass() générique, donc je ne pense pas que je puisse changer cela facilement. Voici la partie du code qui fait ceci:getMethod throws exception non trouvée

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

try { 
    Method mmethod = mclass.getMethod(contractName, parameterTypes); 
} catch (NoSuchMethodException e) {} 

Puis-je résoudre ce problème?

Répondre

2

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.

0

Conformément à this question, vous devez utiliser Integer.TYPE pour faire référence à la primitive int à des fins de réflexion.