2012-08-12 29 views
6

Entonces, tengo un problema extraño. Esta expresión: method.invoke(target, null) tiros java.lang.IllegalArgumentException: número incorrecto de argumentosvarargs y argumento nulo

El problema es que esta expresión es profunda hibernación en el interior (BasicPropertyAccessor $ BasicGetter para ser exactos) y supongo que debería funcionar bien (lo hizo hasta hace poco)

He depurado este problema en eclipse y, de hecho, si yo (en la vista de visualización) llamo a method.invoke(target) o method.invoke(target, (Object[]) null) todo funciona bien. Estoy seguro de que mi clase tiene este captador y no tiene argumentos. Entonces ... la pregunta es, ¿qué demonios está pasando?

EDIT:

  • método es una instancia de java.lang.reflect.Method y puntos a dicho getter
  • de destino es una instancia de la clase con pública X getX() getter
  • JDK 1.6.0_31
  • código en hibernación (BasicPropertyAccessor: 143):

    public Object get(Object target) throws HibernateException { 
        try { 
         return method.invoke(target, null); 
        } 
        catch{ ... } 
    } 
    
+0

¿Qué método está tratando de invocar? – Jeffrey

+0

session.flush(): P Pero al final, hibernate está intentando invocar el getter – mabn

+0

¿cuál es la firma del método? – Bohemian

Respuesta

8

Cuando se pasa un valor null a un método varargs, que podría interpretarse como una de dos cosas:

  • A null array
  • Una matriz con un elemento que es null.

Java elige la primera a menos que null se emita explícitamente al tipo de componente del método varargs. (Se recomienda emitir explícitamente de cualquier manera para mayor claridad, también recibirá una advertencia desagradable en Eclipse si no lo hace)

Al invocar métodos sin argumentos, puede pasar Method.invoke una matriz con 0 elementos, no hay argumentos adicionales (que se traducirá en una matriz vacía), o una matriz null:

public class MethodInvoke { 
    public static void noParams() { 
     System.out.println("noParams called"); 
    } 

    public static void main(String[] args) throws NoSuchMethodException, 
      SecurityException, IllegalAccessException, 
      IllegalArgumentException, InvocationTargetException { 
     Method noParams = MethodInvoke.class.getMethod("noParams"); 
     Object target = null; 
     noParams.invoke(target, new Object[0]); 
     noParams.invoke(target); 
     noParams.invoke(target, null); 
     noParams.invoke(target, (Object[]) null); 
     noParams.invoke(target, (Object) null); // wrong number of arguments 
    } 
} 

lo que parece estar sucediendo es que method.invoke(target, null) se interpreta como method.invoke(target, (Object) null). Eso no es coherente con la forma en que se supone que debe comportarse Java.

¿Está absolutamente seguro de que su método no tiene parámetros?

También noté que en la versión más reciente de Hibernate, explícitamente emitían ese null a Object[].

+0

, borré el repositorio de maven, recreé la base de datos, el espacio de trabajo, los archivos .project y .classpath y comenzó a funcionar. Todavía no tengo idea de por qué se comportó tan raro. – mabn

+0

@mabn Sí, este es un error realmente extraño. Al menos si vuelve a morderte de nuevo, sabrás qué hacer – Jeffrey

0

Si la firma del método es public X getX(), entonces hay no hay parámetros, por lo que llaman de esta manera:

method.invoke(target); 

El primer parámetro del método invoke() es la instancia en la que para invocar el método .

Tenga en cuenta que para los métodos varargs, la forma en que especifica parámetros con comas por ejemplo method(a, b, c) es el azúcar sintáctica para method(new Object[]{a, b, c}: el tipo de parámetro formal es Object[].

+0

Eso no debería importar. Ver mi respuesta – Jeffrey

+0

No puedo cambiar la expresión que proporcionaste, hibernate invoca eso. – mabn

Cuestiones relacionadas