2012-04-18 8 views
7

Wie wird die Zielausnahme einer InvocationTargetException erneut ausgelöst? Ich habe eine Methode, die Reflektion verwendet, um die Methode invoke() innerhalb einer meiner Klassen aufzurufen. Wenn jedoch eine Ausnahme in meinem Code ausgelöst wird, mache ich mir keine Gedanken über die InvocationTargetException und möchte nur die Zielausnahme. Hier ein Beispiel:Erneutes Auslösen einer InvocationTargetException-Zielausnahmebedingung

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

Das primäre Problem, das ich bin vor, dass throw e.getCause Aufruf(); wirft keine Exception, sondern wirft Throwable. Vielleicht nähere ich mich dem falsch?

Antwort

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 für das Hinzufügen in Typ Überprüfung. –

+0

Wie können Sie eine Null-Ursache für eine InvocationTargetException haben? –

+0

Ich glaube nicht, dass es jemals die Ursache sein wird, wenn diese Ausnahme von Method.invoke() ausgelöst wird, aber InvocationTargetException hat einen Konstruktor, der ein Null-Ziel zulässt. In anderen Situationen könnte es also null sein. Ich weiß nicht sicher, aus dem Method.invoke API doc, wenn ein Fehler innerhalb einer InvocationTargetException von geworfen wird, wie es ist. –

0

können Sie jede Ausnahme, die Sie vor, indem Sie das Schlüsselwort throw und das entsprechende Objekt Sie erwischt rethrow:

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

Das OP will die Ursache der InvocationTargetException –

+0

Das wirft nur die gleiche Ausnahme. Ich möchte die InvocationTargetException "essen" und nur das Ziel Exception werfen. –

+0

dann müssen Sie tun: werfen (Ausnahme) e.getCause(); (wie Tim Bender sagte) – Stephan

2

Exception#getCause eine Throwable zurückgibt. Wenn Sie möchten, dass der Compiler denkt, dass Sie ein Exception werfen, müssen Sie es wahrscheinlich umsetzen.

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

Sie können die Ursache erneut auslösen, ohne es ausdrücklich zu erklären.

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

es funktioniert, aber es ist gefährlich. Die stop() -Methode wurde aus gutem Grund nicht weiter unterstützt. Dies ist von stop() API-Dokumentation: Veraltet Diese Methode ist von Natur aus unsicher. Siehe stop() für Details. Eine zusätzliche Gefahr dieser Methode besteht darin, dass sie zum Generieren von Ausnahmen verwendet werden kann, auf die der Zielthread nicht vorbereitet ist (einschließlich geprüfter Ausnahmen, die der Thread möglicherweise nicht werfen könnte, wenn diese Methode nicht verwendet wird). Weitere Informationen finden Sie unter Warum sind Thread.stop, Thread.suspend und Thread.resume veraltet ?. – dgt

0

Das unten ist ausführlich, aber ich mag Reflexion und Casting vermeiden. Ich denke nicht (aber bin mir nicht sicher), dass die Multi-Catch-Syntax von Java 7 nützlich wäre.

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" ; 
      } 
    } 
} 
Verwandte Themen