2011-05-16 16 views
242

Cóż, starałem się zrozumieć i przeczytać, co może spowodować to, ale ja po prostu nie można dostać go:Co może spowodować wyjątek java.lang.reflect.InvocationTargetException?

mam gdzieś w moim kodu to:

try{ 
.. 
m.invoke(testObject); 
.. 
} catch(AssertionError e){ 
... 
} catch(Exception e){ 
.. 
} 

Chodzi o to, że kiedy go próbuje wywołać metodę, którą wyrzuca zamiast jakiegoś innego oczekiwanego wyjątku (konkretnie InvocationTargetException) (w szczególności ArrayIndexOutOfBoundsException). Ponieważ tak naprawdę wiem, jaka metoda jest wywoływana, poszedłem od razu do tego kodu metody i dodałem blok try-catch dla linii, która ma wyrzucać ArrayIndexOutOfBoundsException i tak naprawdę rzuciłem ArrayIndexOutOfBoundsException zgodnie z oczekiwaniami. Jednak po przejściu w górę jakoś zmienia się na InvocationTargetException iw kodzie powyżej catch(Exception e) e jest InvocationTargetException, a nie ArrayIndexOutOfBoundsException zgodnie z oczekiwaniami.

Co może spowodować takie zachowanie lub jak mogę to sprawdzić?

Odpowiedz

263

Dodałeś dodatkowy poziom abstrakcji, wywołując metodę z refleksją. Warstwa refleksyjna zawija każdy wyjątek w InvocationTargetException, który pozwala odróżnić wyjątek faktycznie spowodowany przez niepowodzenie w wywołaniu odbicia (na przykład może być niepoprawna lista argumentów) i niepowodzenie w metodzie o nazwie .

Po prostu rozwiń przyczynę w obrębie InvocationTargetException, a dojdziesz do oryginalnego.

+0

Dzięki, ale jak będę się różnić między (AssertionError e) i (Exception e) na przykład? Czy zawsze otrzymuję wyjątek InvocationTargetException przed rozpakowaniem przyczyny, w której będę się różnić między poszczególnymi wyjątkami? – user550413

+3

@ user550413: Przez rozpakowanie wyjątku i zbadanie go, oczywiście. Zawsze możesz rzucić nim samemu i złapać w ten sposób, jeśli musisz. –

+119

Dla każdego, kto zastanawia się, co to znaczy "odwijać przyczynę w ramach' InvocationTargetException' ", odkryłem, że jeśli wydrukowałeś go za pomocą' exception.printStackTrace() ', po prostu spójrz na" Powodowany przez: " sekcja zamiast sekcji górnej/normalnej. – Jan

16

Z Javadoc z Method.invoke()

Rzuty: InvocationTargetException - jeśli metoda jej zgłasza wyjątek.

Ten wyjątek jest zgłaszany, jeśli metoda zwana wyjątkiem.

+0

Wyobraź sobie, że mam kaskadę instancji 'java.lang.reflect.Proxy' rozszerzających owinięty obiekt. Każdy 'Proxy' zręcznie obsługuje konkretny wyjątek (prawdopodobnie wyrzucany przez owinięty obiekt), używając własnego' InvocationHandler'. Aby wyjątek przeszedł przez tę kaskadę, aż dojdzie do prawidłowego wywołania obsługi/proxy, w każdym 'InvocationHandler', chciałbym złapać' InvocationTargetException', odwijać, sprawdzić, czy zawinięty wyjątek jest 'instanceof' wyjątek do obsługi przez ten 'InvocationHandler'. Jeśli to nie jest "instanceof", rzuciłbym ** wyjątek z zapakowanego ** ... prawda? – Abdull

+0

Zawsze wyrzucałem nieopakowany wyjątek. –

39

jest wyjątek jeśli

InvocationTargetException - jeśli metoda jej zgłasza wyjątek.

więc jeżeli sposób, który został wywołany z odbicia API zgłasza wyjątek (wyjątek wykonawczego na przykład), odbicie API owinąć się wyjątek w InvocationTargetException.

6

To InvocationTargetException prawdopodobnie zawiera Twój ArrayIndexOutOfBoundsException. Nie można powiedzieć z góry, kiedy używa się refleksji, co ta metoda może wyrzucić - dlatego zamiast korzystać z podejścia throws Exception, wszystkie wyjątki są przechwytywane i pakowane w InvocationTargetException.

+0

Dzięki, ale w jaki sposób mogę na przykład różnić się między (AssertionError e) i (Exception e)? Czy zawsze otrzymuję wyjątek InvocationTargetException przed rozpakowaniem przyczyny, w której będę się różnić między poszczególnymi wyjątkami? – user550413

31

Użyj metody getCause() na InvocationTargetException, aby pobrać oryginalny wyjątek.

0
  1. Lista wszystkich plików jar z trybu Eclipse Navigator
  2. Upewnij się, że wszystkie pliki jar są w trybie binarnym
+2

W jaki sposób dokładnie sprawdzasz pliki jar w trybie binarnym, wyświetlając je w Nawigatorze? – William

1

This opisuje coś,

InvocationTargetException jest sprawdzana wyjątek która opakowuje wyjątek wygenerowany przez wywoływaną metodę lub konstruktor. Po wydaniu 1.4 ten wyjątek został zmodernizowany w celu dostosowania go do ogólnego mechanizmu łączenia wyjątków. "Wyjątek docelowy", który jest podany w czasie budowy i dostępny za pośrednictwem metody getTargetException(), jest obecnie znany jako przyczyna i może być dostępny za pośrednictwem metody Throwable.getCause(), jak również wspomniany wyżej "spuściznę" w postaci . metoda."

0

Ten wyjątek jest zgłaszany, jeśli metoda bazowa (metoda zwana odbiciem) zgłasza wyjątek.

Tak więc, jeśli metoda, która została wywołana przez odbicie API, zgłasza wyjątek (jak na przykład wyjątek środowiska wykonawczego), interfejs API odwzorowujący zawinie wyjątek do wyjątku InvocationTargetException.

8

To będzie drukować dokładną linię kodu w konkretnym sposobie, który po wywołaniu podniesionej wyjątek:

try { 

    // try code 
    .. 
    m.invoke(testObject); 
    .. 

} catch (InvocationTargetException e) { 

    // Answer: 
    e.getCause().printStackTrace(); 
} catch (Exception e) { 

    // generic exception handling 
    e.printStackTrace(); 
} 
+0

Dzięki; to pomogło mi uświadomić sobie, że mój problem nie był w samym odbiciu, ale w ramach przywoływanej metody. –

-6

Błąd zniknął po Zrobiłem chemi-> Uruchom> Uruchom xPackaging xDoclet-.

W mojej przestrzeni roboczej, w eclipsie.

1

można porównać z oryginalnym klasy wyjątków przy użyciu getCause() metoda tak:

try{ 
    ... 
} catch(Exception e){ 
    if(e.getCause().getClass().equals(AssertionError.class)){ 
     // handle your exception 1 
    } else { 
     // handle the rest of the world exception 
    } 
} 
0

byłem stoi ten sam problem. Użyłem e.getCause(). GetCause(), a następnie stwierdziłem, że było to spowodowane złymi parametrami, które przekazywałem. Podczas pobierania wartości jednego z parametrów wystąpił wyjątek nullPointerException. Mam nadzieję, że to ci pomoże.

0

miałem java.lang.reflect.InvocationTargetException błąd na oświadczenie wzywające obiektu rejestratora w zewnętrznym class wewnątrz try/catch bloku w moim class.

Krocząc przez debugger kodu w Eclipse & unoszące się myszką na rachunku rejestratora widziałem rejestratora object był null (niektóre stałe zewnętrzne potrzebne do wystąpienia na samym szczycie mojej class).

Powiązane problemy