java - Error de número de argumentos incorrecto al invocar un método
reflection illegalargumentexception (5)
El método Method.invoke toma el objeto para recibir la llamada al método y una matriz de los argumentos del método. Como su método toma un argumento, la matriz dada debe tener un tamaño de uno.
intenta crear una nueva matriz con tamaño 1:
someMethod.invoke(anObject, new Object[] {parameters});
Tenga en cuenta que el único valor en esta matriz puede ser nulo. Esto simularía un objeto de anObject.someMethod(null)
Tengo clase AClass
y un método someMethod
que obtiene una matriz de Object
como parámetro.
public class AClass {
public void someMethod(Object[] parameters) {
}
}
En general, cuando intento invocar este método en el objeto que he creado y le doy una matriz de objetos como parámetro a este método
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);
Obtengo "error de número de argumentos incorrecto". ¿Qué me estoy perdiendo?
Eso estará 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);
Tenga cuidado con el segundo parámetro del método de invocación. Es el Objeto [] en sí mismo, y el tipo de argumento de su método es el Objeto [] también.
Los parámetros a invoke
son una matriz de Object
; sus parámetros deben ser un Object[]
contenga el Object[]
que está pasando a someMethod
.
No necesita crear una matriz inmediata para hacer esto, ya que la firma de invoke
es invoke(Object, Object...)
, pero en su caso, está intentando pasar una matriz vacía . Si quieres pasar en nulo:
Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);
Sin embargo, en última instancia, las otras respuestas son correctas: debe pasar un Object[]
contenga una entrada para cada uno de los parámetros de los métodos .
Para ampliar un poco lo que dicen oria y biaobiaoqi. . .
Lo que probablemente te está confundiendo aquí es que Method.invoke(Object, Object...)
normalmente puede tomar los argumentos "en línea", por así decirlo; cuando el compilador ve algo así como someMethod.invoke(someObject, arg1, arg2)
, crea implícitamente una new Object[]{arg1, arg2}
matriz new Object[]{arg1, arg2}
y luego la pasa a Method.invoke
. Method.invoke
luego pasa los elementos de esa matriz como argumentos al método que está invocando. Hasta ahora tan bueno.
Pero cuando el compilador ve algo así como someMethod.invoke(someObject, someArray)
, asume que ya has empaquetado los argumentos en una matriz; así que no los volverá a empaquetar. Entonces, Method.invoke
intentará pasar los elementos de someArray
como argumentos al método que está invocando, en lugar de pasar a someArray
como un argumento.
(Así es como funciona la notación ...
; acepta una matriz que contiene elementos del tipo apropiado o cero o más argumentos del tipo apropiado).
Entonces, como han dicho orien y biaobiaoqi, debe volver a envolver sus parameters
en una matriz adicional, el new Object[] {parameters}
, para que los parameters
sí mismos se pasen a su método.
¿Tiene sentido?
prueba esto:
someMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
Obtuve al generar automáticamente una versión de Reflection API de su código con 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});
}
}