J'ai la classe AClass
et une méthode someMethod
qui obtient un tableau Object
comme paramètre.
public class AClass {
public void someMethod(Object[] parameters) {
}
}
En général, lorsque j'essaie d'invoquer cette méthode sur l'objet que j'ai créé et de donner un tableau d'objets en paramètre à cette méthode
Object[] parameters; // lets say this object array is null
Class class = Class.forName("AClass");
Object anObject = class.newInstance();
Method someMethod = class.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, parameters);
J'obtiens "erreur de nombre d'arguments incorrect". Qu'est-ce que je rate?
Ce sera bien.
Object[] parameters ={new Object()}; // lets say this object array is null
Class clas = Class.forName("AClass");
Object anObject = clas.newInstance();
Object[] param ={parameters};
Method someMethod = clas.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, param);
Faites attention au deuxième paramètre de la méthode invoke. C'est Object [] lui-même, et le type d'argument de votre méthode est Object [] également.
Pour développer un peu ce que disent orien et biaobiaoqi. . .
Ce qui vous dérange probablement ici, c'est que Method.invoke(Object, Object...)
peut généralement prendre les arguments "en ligne", pour ainsi dire; lorsque le compilateur voit quelque chose comme someMethod.invoke(someObject, arg1, arg2)
, il crée implicitement un tableau new Object[]{arg1, arg2}
puis passe ce tableau à Method.invoke
. Method.invoke
Passe ensuite les éléments de ce tableau comme arguments à la méthode que vous invoquez. Jusqu'ici tout va bien.
Mais lorsque le compilateur voit quelque chose comme someMethod.invoke(someObject, someArray)
, il suppose que vous avez déjà empaqueté les arguments dans un tableau; afin de ne plus les reconditionner. Ainsi, Method.invoke
Essaiera de passer les éléments de someArray
comme arguments à la méthode que vous invoquez, plutôt que de passer someArray
lui-même comme argument.
(C'est toujours ainsi que fonctionne la notation ...
; Elle accepte soit un tableau contenant des éléments du type approprié, o zéro ou plusieurs arguments du type approprié .)
Ainsi, comme l'ont dit orien et biaobiaoqi, vous devez reconditionner votre parameters
dans un tableau supplémentaire, new Object[] {parameters}
, Afin que parameters
lui-même finisse par être transmis à votre méthode.
Cela a-t-il du sens?
La méthode Method.invoke prend l'objet pour recevoir l'appel de méthode et un tableau des arguments de la méthode. Comme votre méthode prend un argument, le tableau donné doit avoir une taille d'un.
essayez de créer un nouveau tableau de taille 1:
someMethod.invoke(anObject, new Object[] {parameters});
Notez que la seule valeur de ce tableau peut être nulle. Cela simulerait anObject.someMethod(null)
Les paramètres de invoke
sont un tableau de Object
; vos paramètres doivent être un Object[]
contenant le Object[]
que vous passez à someMethod
.
Vous n'avez pas besoin de créer un tableau immédiat pour le faire, car la signature invoke
est invoke(Object, Object...)
, mais dans votre cas, vous essayez de passer un vide tableau. Si vous souhaitez passer null:
Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);
En fin de compte, cependant, les autres réponses sont correctes: vous devez passer un Object[]
Contenant une entrée pour chacun des paramètres des méthodes.
essaye ça:
someMethod.invoke(anObject, new .Java.lang.Object[1][]{parameters});
J'ai obtenu en générant automatiquement une version de l'API Reflection de votre code avec dp4j:
$ javac -cp dp4j-1.2-jar-with-dependencies.jar -Averbose=true AClass.Java
AClass.Java:10: Note:
import com.dp4j.*;
public class AClass {
public AClass() {
super();
}
public void someMethod(Object[] parameters) {
}
@Reflect(all = true)
public static void main(String... args) throws ... {
Object[] parameters = null;
...
AClass anObject;
anObject = (.AClass)aClassConstructor.newInstance();
Java.lang.reflect.Method someMethodWithArrayMethod = null;
someMethodWithArrayMethod = Class.forName("AClass").getDeclaredMethod("someMethod", .Java.lang.Object[].class);
someMethodWithArrayMethod.setAccessible(true);
someMethodWithArrayMethod.invoke(anObject, new .Java.lang.Object[1][]{parameters});
}
}