java reflection illegalargumentexception

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}); } }