2012-04-18 17 views
7

¿Cómo se vuelve a lanzar la excepción de destino de una InvocationTargetException. Tengo un método que usa la reflexión para llamar al método invoke() dentro de una de mis clases. Sin embargo, si hay una excepción lanzada dentro de mi código, no me preocupa la InvocationTargetException y solo deseo la excepción de destino. Aquí hay un ejemplo:Volver a lanzar una excepción de destino InvocationTargetException

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throws Exception { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } catch (InvocationTargetException e) { 
     // throw the target exception here 
    } 
} 

El problema principal al que me enfrento es que la llamada arroja e.getCause(); no arroja una excepción, sino que lanza una Throwable. Tal vez me estoy acercando a esto incorrectamente?

Respuesta

12
catch (InvocationTargetException e) { 
    if (e.getCause() instanceof Exception) { 
     throw (Exception) e.getCause(); 
    } 
    else { 
     // decide what you want to do. The cause is probably an error, or it's null. 
    } 
} 
+0

+1 para agregar en la comprobación de tipos. –

+0

¿Cómo puede tener una causa 'nula' para una InvocationTargetException? –

+0

No creo que alguna vez sea la causa cuando Method.invoke() arroje esta excepción, pero InvocationTargetException tiene un constructor que permite un objetivo nulo, por lo que en otras situaciones, puede ser nulo. No estoy seguro, desde el documento API de Method.invoke, si un error está dentro de una InvocationTargetException de throw as is. –

0

Puede volver a lanzar ninguna excepción has cogido antes mediante el uso de la palabra clave tiro y el objeto correspondiente que pillan:

catch (XXXException e) 
{ 
     throw e; 
} 
+0

El OP quiere la causa de InvocationTargetException –

+0

Esto arroja la misma excepción. Quiero "comer" InvocationTargetException y lanzar solo la excepción de destino. –

+0

luego tienes que hacer: throw (Exception) e.getCause(); (como Tim Bender dijo) – Stephan

2

Exception#getCause devuelve un Throwable. Si quieres que el compilador piense que estás lanzando un Exception, entonces probablemente necesites lanzarlo.

throw (Exception) e.getCause(); 
-1

Usted puede volver a lanzar la causa sin declararlo explícitamente.

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throw /* known exceptions */ { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } catch (InvocationTargetException e) { 
     // rethrow any exception. 
     Thread.currentThread().stop(e.getCause()); 
    } 
} 
+0

funciona, pero es peligroso. El método stop() ha sido desaprobado por una buena razón. Esto es de stop() API docs: Deprecated Este método es intrínsecamente inseguro. Ver stop() para más detalles. Un peligro adicional de este método es que puede usarse para generar excepciones que el hilo de destino no está preparado para manejar (incluidas las excepciones comprobadas que el hilo no podría lanzar, si no fuera por este método). Para obtener más información, consulte ¿Por qué Thread.stop, Thread.suspend y Thread.resume están en desuso ?. – dgt

0

Lo siguiente es detallado, pero me gusta evitar la reflexión y el casting. No creo (pero no estoy seguro) que la sintaxis multi catch de Java 7 sea útil.

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throw KnownException_1 , KnownException_2 , ... , KnownException_n { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } 
    catch (InvocationTargetException cause) 
    { 
      assert cause . getCause () != null : "Null Cause" ; 
      try 
      { 
       throw cause . getCause () ; 
      } 
      catch (KnownException_1 c) 
      { 
       throw c 
      } 
      catch (KnownException_2 c) 
      { 
       throw c 
      } 
      ... 
      catch (KnownException_n c) 
      { 
       throw c 
      } 
      catch (RuntimeException c) 
      { 
       throw c ; 
      } 
      catch (Error c) 
      { 
       throw c ; 
      } 
      catch (Throwable c) 
      { 
       assert false : "Unknown Cause" ; 
      } 
    } 
} 
Cuestiones relacionadas