Różnica między użyciem Throwable i Exception w try catch

Odpowiedzi:

247

Łapanie Throwableobejmuje elementy należące do podklasy Error. Zasadniczo nie powinieneś tego robić, chyba że na najwyższym poziomie wątku „catch all”, w którym chcesz się zalogować lub w inny sposób obsłużyć absolutnie wszystko, co może pójść nie tak. Byłoby to bardziej typowe w aplikacjach typu framework (na przykład na serwerze aplikacji lub frameworku testującym), w których może on uruchamiać nieznany kod i nie powinien mieć na niego wpływu wszystko , co jest nie tak z tym kodem, jak to tylko możliwe.

Yishai
źródło
30
Prawdopodobnie najlepiej byłoby tutaj wyjaśnić nieco hierarchię.
Xonatron,
11
Kontekst tej odpowiedzi: Throwable zawiera zarówno Błąd, jak i Wyjątek jako podklasy, więc pierwsza próba / złap obejmuje drugą, ale zwykle zbyt szeroką.
Noel
2
Obejmuje także zdefiniowane przez użytkownika bezpośrednie podklasy Throwable i instancje samego Throwable. Nic nie throw new Throwable();stoi na przeszkodzie, aby pisać , więc jest to jedyny sposób, aby naprawdę złapać wszystko.
Antymon
3
Chociaż zaakceptowane, nie odpowiada to na pytanie, ponieważ większość odpowiedzi opisuje najlepszą praktykę wychwytywania zarówno wyjątku, jak i Throwable, a pytanie dotyczyło różnicy (jak w przypadku, kiedy użyć, kiedy, gdy chcę). „Zawiera elementy, które podklasują błąd” to jedyna określona różnica i naprawdę wyczerpująca odpowiedź: co to jest błąd? Dlaczego to ważne, że to obejmuje? Wszelkie inne różnice lub najlepsze praktyki?
Oded Niv,
@OdedNiv „Co to jest błąd? Dlaczego to ważne, że zawiera błąd?” możesz zadać pytanie w innym pytaniu.
Kronen
182

Pierwsza łapie wszystkie podklasy Throwable(w tym Exceptioni Error), druga łapie wszystkie podklasy Exception.

Errorjest programowo niemożliwy do odzyskania w jakikolwiek sposób i zwykle nie można go złapać, z wyjątkiem celów rejestrowania (które przechodzą ponownie). Exceptionjest programowo odzyskiwalny. Jego podklasa RuntimeExceptionwskazuje na błąd programowania i zwykle nie można go również złapać.

BalusC
źródło
37
Zaskakujące jest to, że 4 lata po tej odpowiedzi większość narzędzi do analizy kodu będzie nadal zgłaszać wyłapanie jako błąd krytyczny . Rejestrowanie jest bardzo ważnym powodem do złapania Throwable. Lata rozwoju serwerów mówią mi, że 1) Rejestrowanie nastąpi pomimo uzyskania Errori 2) O ile nie będzie logowania, możesz nigdy nie zostać powiadomiony o wystąpieniu OOM, co powoduje, że zastanawiasz się, dlaczego serwer zaczął zachowywać się „zabawnie”
Bruno Grieder
4
Co to programmatically unrecoverableznaczy dokładnie? Czy jest tak poważny, że nie możemy w zasadzie wywołać ŻADNEJ metody Java po jej złapaniu (rejestrowanie itp.) Bez szansy na uzyskanie nieprzewidzianego zachowania z JVM?
Alexander Abakumov
Its subclass RuntimeException indicates a programming error: Nie jestem pewien, czy zgadzam się z tym stwierdzeniem. Jeśli to prawda, oznacza to, że wszystkie oczekiwane wyjątki powinny być sprawdzone. Co się stanie, jeśli spodziewam się, że coś może zawieść i nie da się go odzyskać w mojej aplikacji, ale chcę przynajmniej rzucić znaczący wyjątek? Użycie sprawdzonego wyjątku w tym przypadku wydaje się bezużyteczne i tworzy kod bojlera.
Nom1fan
22

Thowablełapie naprawdę wszystko, nawet ThreadDeath, który jest domyślnie wyrzucany, aby zatrzymać wątek z obecnie przestarzałej Thread.stop()metody. Więc łapiąc Throwablemożesz być pewien, że nigdy nie opuścisz bloku try, przynajmniej nie przechodząc przez blok catch, ale powinieneś być przygotowany na obsługę OutOfMemoryErrori InternalErrorlub StackOverflowError.

Łapanie Throwablejest najbardziej przydatne w zewnętrznych pętlach serwerów, które delegują wszelkiego rodzaju żądania do kodu zewnętrznego, ale same mogą nigdy się nie kończyć, aby utrzymać usługę przy życiu.

x4u
źródło
21

Throwablejest super klasy Exception, jak również Error. W normalnych przypadkach powinniśmy zawsze wyłapywać podklasy Exception, aby pierwotna przyczyna się nie zgubiła.

Tylko specjalne przypadki, w których widzisz możliwość, że coś pójdzie nie tak, co nie kontroluje twojego kodu Java, powinieneś złapać Errorlub Throwable.

Pamiętam, jak łapałem Throwable'a, by oznaczyć, że natywna biblioteka nie jest załadowana.

rai.skumar
źródło
0

Widziałem, jak ludzie używają Throwable do wychwytywania błędów, które mogą się zdarzyć z powodu awarii / braku dostępu do sieci.

Włócznia A1
źródło