2012-04-18 13 views
7

W jaki sposób można ponownie rzutować docelowy wyjątek wyjątku InvocationTargetException. Mam metodę, która używa odbicia, aby wywołać metodę invoke() w ramach jednej z moich klas. Jeśli jednak w moim kodzie znajduje się wyjątek, nie martwię się wyjątkiem InvocationTargetException i chcę tylko wyjątku docelowego. Oto przykład:Ponownie wyrzuć wyjątek celu wyjątku 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 
    } 
} 

Podstawowym problemem jestem stoi to, że wywołanie rzut e.getCause(); nie rzuca wyjątku, ale raczej rzuca Throwable. Być może podchodzę do tego niepoprawnie?

Odpowiedz

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 za dodanie sprawdzenia typu. –

+0

Jak można uzyskać przyczynę 'null' dla wyjątku InvocationTargetException? –

+0

Nie sądzę, że będzie kiedykolwiek przyczyną tego wyjątku jest wywoływana przez Method.invoke(), ale InvocationTargetException ma konstruktora dopuszczające zerowy cel, więc w innych sytuacjach może być zerowy. Nie wiem na pewno, z Dokumentu API Method.invoke, jeśli błąd jest zawijany wewnątrz wyjątku InvocationTargetException zgłaszanego w niezmienionym stanie. –

0

Można rethrow żadnego wyjątku złowione wcześniej za pomocą słowa kluczowego throw i odpowiedni obiekt, który złapany:

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

PO chce przyczynę InvocationTargetException –

+0

To właśnie rzuca ten sam wyjątek. Chcę "zjeść" wyjątek InvocationTargetException i rzucić wyjątek docelowy. –

+0

następnie musisz zrobić: rzut (wyjątek) e.getCause(); (jak powiedział Tim Bender) – Stephan

2

Exception#getCause zwraca Throwable. Jeśli chcesz, aby kompilator myślał, że rzucasz Exception, prawdopodobnie musisz go rzucić.

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

Można rethrow przyczynę bez deklarowania go wyraźnie.

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

to działa, ale jest niebezpieczne. Metoda stop() została uznana za przestarzałą z dobrego powodu. Jest to z dokumentacji stop() API: Przestarzałe Ta metoda jest z natury niebezpieczna. Szczegółowe informacje można znaleźć w stop(). Dodatkowym niebezpieczeństwem związanym z tą metodą jest to, że można ją wykorzystać do generowania wyjątków, których docelowy wątek nie jest przygotowany do obsługi (w tym sprawdzone wyjątki, których wątek nie mógłby wyrzucić, gdyby nie ta metoda). Aby uzyskać więcej informacji, zobacz Dlaczego Thread.stop, Thread.suspend i Thread.resume Przestarzałe ?. – dgt

0

Poniżej jest pełna gadka, ale lubię unikać refleksji i rzucania. Nie sądzę (ale nie jestem pewien), że przydatna byłaby składnia wielu haseł Java 7.

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" ; 
      } 
    } 
} 
Powiązane problemy