Tak powiedział Joshua Bloch w „ Effective Java ”
Użyj sprawdzonych wyjątków dla warunków do odzyskania i wyjątków czasu wykonywania dla błędów programowania (pozycja 58 w 2. edycji)
Zobaczmy, czy dobrze to rozumiem.
Oto moje rozumienie sprawdzonego wyjątku:
try{
String userInput = //read in user input
Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
id = 0; //recover the situation by setting the id to 0
}
1. Czy powyższy uważa się za sprawdzony wyjątek?
2. Czy RuntimeException jest niesprawdzonym wyjątkiem?
Oto moje rozumienie niesprawdzonego wyjątku:
try{
File file = new File("my/file/path");
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//3. What should I do here?
//Should I "throw new FileNotFoundException("File not found");"?
//Should I log?
//Or should I System.exit(0);?
}
4. Czy powyższy kod nie może być sprawdzonym wyjątkiem? Czy mogę spróbować przywrócić taką sytuację? Czy mogę? (Uwaga: moje trzecie pytanie znajduje się catch
powyżej)
try{
String filePath = //read in from user input file path
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//Kindly prompt the user an error message
//Somehow ask the user to re-enter the file path.
}
5. Dlaczego ludzie to robią?
public void someMethod throws Exception{
}
Dlaczego pozwalają na wyjątek? Czy wcześniejsza obsługa błędu nie jest lepsza? Po co bańkować?
6. Czy mam wykreślić dokładny wyjątek, czy zamaskować go za pomocą wyjątku?
Poniżej moje odczyty
DataSeries
klasę, która przechowuje dane, które zawsze muszą pozostawać w porządku czasowym. Istnieje metoda dodania nowegoDataPoint
na końcuDataSeries
. Jeśli cały mój kod działa poprawnie w całym projekcie,DataPoint
nigdy nie należy go dodawać na końcu, który ma wcześniejszą datę niż ta na końcu. Każdy moduł w całym projekcie jest zbudowany z tego truizmu. Sprawdzam jednak ten warunek i rzucam niezaznaczony wyjątek, jeśli tak się stanie. Dlaczego? Jeśli tak się stanie, chcę wiedzieć, kto to robi i to naprawić.Odpowiedzi:
Wiele osób twierdzi, że sprawdzone wyjątki (tj. Te, które należy wyraźnie złapać lub powrócić) nie powinny być w ogóle używane. Zostały one wyeliminowane na przykład w języku C #, a większość języków ich nie ma. Możesz więc zawsze rzucić podklasę
RuntimeException
(niezaznaczony wyjątek)Myślę jednak, że sprawdzone wyjątki są przydatne - są one używane, gdy chcesz zmusić użytkownika interfejsu API do zastanowienia się, jak poradzić sobie z wyjątkową sytuacją (jeśli można ją odzyskać). Po prostu sprawdzone wyjątki są nadużywane na platformie Java, co sprawia, że ludzie ich nienawidzą.
Oto mój rozszerzony pogląd na ten temat .
Co do poszczególnych pytań:
Czy
NumberFormatException
rozważany jest sprawdzony wyjątek?Nie
NumberFormatException
jest zaznaczone (= podklasaRuntimeException
). Dlaczego? Nie wiem (ale powinna istnieć metodaisValidInteger(..)
)Czy
RuntimeException
niesprawdzony wyjątek?Tak, dokładnie.
Co mam tu zrobić?
Zależy to od tego, gdzie jest ten kod i co chcesz zrobić. Jeśli jest w warstwie interfejsu użytkownika - złap go i pokaż ostrzeżenie; jeśli jest w warstwie serwisowej - nie łap go wcale - pozwól mu się bąbelkować. Tylko nie połykaj wyjątku. Jeśli w większości przypadków wystąpi wyjątek, wybierz jeden z tych:
Czy powyższy kod nie może być sprawdzonym wyjątkiem? Czy mogę spróbować przywrócić taką sytuację? Czy mogę?
To mogło być. Ale nic nie stoi na przeszkodzie, aby złapać również niesprawdzony wyjątek
Dlaczego ludzie dodają klasę
Exception
w klauzuli rzucania?Najczęściej dlatego, że ludzie są leniwi, zastanawiając się, co złapać, a co rzucić. Rzucanie
Exception
jest złą praktyką i należy jej unikać.Niestety, nie ma jednej reguły, która pozwala określić, kiedy złapać, kiedy ponownie rzucić, kiedy użyć zaznaczone, a kiedy użyć niesprawdzonych wyjątków. Zgadzam się, że powoduje to wiele zamieszania i dużo złego kodu. Ogólną zasadę określa Bloch (zacytowałeś jej część). A ogólna zasada polega na ponownym odrzuceniu wyjątku od warstwy, w której można go obsłużyć.
źródło
To, czy coś jest „sprawdzonym wyjątkiem”, nie ma nic wspólnego z tym, czy go złapiesz, czy co robisz w bloku catch. Jest to właściwość klas wyjątków. Wszystko, co jest podklasą
Exception
z wyjątkiem dlaRuntimeException
jej podklasy jest sprawdzana wyjątkiem.Kompilator Java zmusza Cię do przechwycenia sprawdzonych wyjątków lub zadeklarowania ich w podpisie metody. Miało to poprawić bezpieczeństwo programu, ale wydaje się, że większość uważa, że nie warto tworzyć problemów projektowych.
Ponieważ to jest cały punkt wyjątków. Bez tej możliwości nie potrzebujesz wyjątków. Umożliwiają one obsługę błędów na wybranym przez Ciebie poziomie, zamiast zmuszać Cię do radzenia sobie z nimi przy użyciu metod niskiego poziomu, w których pierwotnie występują.
źródło
Throwable
napisano w javadoc : „Throwable i każda podklasa Throwable, która nie jest również podklasą RuntimeException lub Error, są uważane za sprawdzone wyjątki”Czy powyższe jest uważane za sprawdzony wyjątek? No Fakt, że są obsługi wyjątku nie sprawiają, że
Checked Exception
jeśli jest toRuntimeException
.Czy ? tak
RuntimeException
unchecked exception
Checked Exceptions
sąsubclasses
zjava.lang.Exception
Unchecked Exceptions
sąsubclasses
zjava.lang.RuntimeException
Wywołania sprawdzające wyjątki muszą być ujęte w bloku try {} lub obsługiwane na wyższym poziomie w obiekcie wywołującym metodę. W takim przypadku bieżąca metoda musi zadeklarować, że zgłasza wspomniane wyjątki, aby osoby dzwoniące mogły dokonać odpowiednich ustaleń w celu obsługi wyjątku.
Mam nadzieję że to pomoże.
Odp .: Tak, to bardzo dobre pytanie i ważna uwaga dotycząca projektu. Wyjątek klasy jest bardzo ogólną klasą wyjątków i może być używany do zawijania wewnętrznych wyjątków niskiego poziomu. Lepiej utwórz niestandardowy wyjątek i zawiń w nim. Ale i duży - nigdy nie jest niejasny w pierwotnej pierwotnej przyczynie. Na przykład
Don't ever
wykonaj następujące czynności -Zamiast tego wykonaj następujące czynności:
Usunięcie pierwotnej przyczyny źródłowej powoduje, że faktyczna przyczyna nie do odzyskania jest koszmarem dla zespołów wsparcia produkcji, do których mają dostęp tylko do dzienników aplikacji i komunikatów o błędach. Chociaż ten ostatni jest lepszym projektem, ale wiele osób nie korzysta z niego często, ponieważ programiści po prostu nie przekazują podstawowej wiadomości dzwoniącemu. Zrób więc
Always pass on the actual exception
wyraźną notatkę: z powrotem, niezależnie od tego, czy jest zawarty w wyjątku specyficznym dla aplikacji.RuntimeException
Z zasady nie należy próbować łapać. Zazwyczaj sygnalizują błąd programowania i należy je pozostawić w spokoju. Zamiast tego programista powinien sprawdzić stan błędu przed wywołaniem kodu, który może spowodować błądRuntimeException
. Na przykład:To zła praktyka programowania. Zamiast tego należy wykonać kontrolę zerową, jak -
Ale są chwile, kiedy takie sprawdzanie błędów jest kosztowne, takie jak formatowanie liczb, rozważ to -
W tym przypadku sprawdzanie błędów przed wywołaniem nie jest warte wysiłku, ponieważ zasadniczo oznacza zduplikowanie całego kodu konwersji łańcucha na liczbę całkowitą w metodzie parseInt () - i jest podatne na błędy, jeśli zostanie zaimplementowane przez programistę. Lepiej więc po prostu zrezygnować z try-catch.
Tak więc
NullPointerException
iNumberFormatException
obaRuntimeExceptions
, łapanie aNullPointerException
powinno zostać zastąpione wdzięcznym zerowaniem, podczas gdy ja polecamNumberFormatException
jawne łapanie, aby uniknąć możliwego wprowadzenia kodu podatnego na błędy.źródło
exception
bąbelki, czy powinienem wykreślić dokładny wyjątek lub zamaskować go za pomocąException
. Piszę kod na jakimś starszym kodzie i jestemException
rozrzucony po całym świecie. Zastanawiam się, czy to jest właściwe zachowanie?LoginFailureException(sqle)
?LoginFailureException
rozszerzaException
i ogłasza konstruktorapublic LoginFailureException(Throwable cause) { super(cause) }
1. Jeśli nie masz pewności co do wyjątku, sprawdź interfejs API:
2) Tak, i każdy wyjątek, który go rozszerza.
3) Nie ma potrzeby łapania i rzucania tego samego wyjątku. W takim przypadku możesz wyświetlić nowe okno dialogowe pliku.
4 FileNotFoundException to już sprawdzonym wyjątkiem.
5 Jeśli oczekuje się, że wywołanie metody
someMethod
złapie wyjątek, ten drugi może zostać wyrzucony. Po prostu „podaje piłkę”. Przykładem tego może być użycie własnych metod prywatnych i obsłużenie wyjątku w metodzie publicznej.Dobrym czytaniem jest sam dokument Oracle: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html
W specyfikacji języka Java znajduje się również ważna informacja :
Najważniejsze jest to, że możesz złapać dowolne
RuntimeException
, ale nie jest to wymagane i, w rzeczywistości, wdrożenie nie jest wymagane do zachowania tych samych niezgłoszonych wyjątków, ponieważ nie są one częścią umowy.źródło
exception
bąbelki, czy powinienem wykreślić dokładny wyjątek lub zamaskować go za pomocąException
. Piszę kod na jakimś starszym kodzie i jestemException
rozrzucony po całym świecie. Zastanawiam się, czy to jest właściwe zachowanie?1) Nie, wyjątek NumberFormatException jest niezaznaczonym wyjątkiem. Nawet jeśli go złapałeś (nie jest to wymagane), ponieważ nie jest zaznaczony. Jest tak, ponieważ jest to podklasa,
IllegalArgumentException
której jest podklasąRuntimeException
.2)
RuntimeException
jest źródłem wszystkich niezaznaczonych wyjątków. Każda podklasaRuntimeException
nie jest zaznaczona. Wszystkie inne wyjątki iThrowable
są sprawdzane z wyjątkiem błędów (które wchodzą w zakresThrowable
).3/4) Możesz ostrzec użytkownika, że wybrał nieistniejący plik i poprosić o nowy. Lub po prostu przestań informować użytkownika, że wprowadził coś nieprawidłowego.
5) Rzucanie i łapanie
'Exception'
jest złą praktyką. Ale bardziej ogólnie, możesz wprowadzić inne wyjątki, aby osoba dzwoniąca mogła zdecydować, jak sobie z tym poradzić. Na przykład, jeśli napisałeś bibliotekę do obsługi odczytu danych wejściowych pliku, a do Twojej metody przekazano nieistniejący plik, nie masz pojęcia, jak sobie z tym poradzić. Czy dzwoniący chce zapytać ponownie lub wyjść? Rzucasz wyjątek w górę łańcucha z powrotem do dzwoniącego.W wielu przypadkach
unchecked Exception
występuje, ponieważ programista nie zweryfikował danych wejściowych (w przypadkuNumberFormatException
pierwszego pytania). Właśnie dlatego ich złapanie jest opcjonalne, ponieważ istnieją bardziej eleganckie sposoby uniknięcia generowania tych wyjątków.źródło
exception
bąbelki, czy powinienem wykreślić dokładny wyjątek lub zamaskować go za pomocąException
. Piszę kod na jakimś starszym kodzie i jestemException
rozrzucony po całym świecie. Zastanawiam się, czy to jest właściwe zachowanie?Sprawdzone - podatne na zdarzenie. Sprawdzono w czasie kompilacji.
Np. FileOperations
Niezaznaczone - z powodu złych danych. Sprawdzone w czasie wykonywania.
Na przykład..
Tutaj wyjątek wynika z złych danych i nie można go w żaden sposób ustalić podczas kompilacji.
źródło
Sprawdzone wyjątki są sprawdzane w czasie kompilacji przez JVM i jego powiązane z zasobami (pliki / db / stream / socket itp.). Motywem sprawdzanego wyjątku jest to, że w czasie kompilacji, jeśli zasoby nie są dostępne, aplikacja powinna zdefiniować alternatywne zachowanie, aby poradzić sobie z tym w bloku catch / wreszcie.
Niezaznaczone wyjątki to błędy czysto programowe, błędne obliczenia, zerowe dane, a nawet awarie logiki biznesowej mogą prowadzić do wyjątków w czasie wykonywania. Absolutnie dobrze jest obsługiwać / wychwytywać niesprawdzone wyjątki w kodzie.
Wyjaśnienie pochodzi z http://coder2design.com/java-interview-questions/
źródło
Mój absolutnie ulubiony opis różnicy między niezaznaczonymi i sprawdzonymi wyjątkami znajduje się w artykule na temat samouczka Java, „ Niezaznaczone wyjątki - kontrowersje ” (przepraszam, że wszystkie podstawowe elementy tego postu - ale, hej, podstawy są czasami najlepsze):
Sedno „jakiego rodzaju wyjątku do rzucenia” ma charakter semantyczny (do pewnego stopnia), a powyższy cytat stanowi doskonałą wskazówkę (stąd wciąż jestem pod wrażeniem przekonania, że C # pozbył się sprawdzonych wyjątków - szczególnie jak argumentuje Liskov ich przydatność).
Reszta staje się zatem logiczna: na które wyjątki kompilator oczekuje, że ja odpowiem wprost? Te, od których oczekujesz powrotu klienta.
źródło
Aby odpowiedzieć na ostatnie pytanie (inni wydają się dokładnie odpowiedzieć powyżej): „Czy mam wykreślić konkretny wyjątek, czy zamaskować go za pomocą wyjątku?”
Zakładam, że masz na myśli coś takiego:
Nie, zawsze deklaruj najbardziej precyzyjny możliwy wyjątek lub listę takich. Wyjątki, które deklarujesz jako metodę do rzucania, są częścią umowy między twoją metodą a dzwoniącym. Rzucanie
"FileNotFoundException"
oznacza, że możliwe jest, że nazwa pliku jest nieprawidłowa i plik nie zostanie znaleziony; dzwoniący będzie musiał poradzić sobie z tym inteligentnie. RzucanieException
oznacza „Hej, kurwa się zdarza. Rozdanie”. Co jest bardzo biedneAPI
.W komentarzach do pierwszego artykułu jest kilka przykładów, w których „rzuty
Exception
” są prawidłową i rozsądną deklaracją, ale nie dotyczy to większościnormal
kodu, który kiedykolwiek napiszesz.źródło
Wyjątki środowiska wykonawczego : wyjątki środowiska wykonawczego są nazywane wyjątkami niezaznaczonymi. Wszystkie pozostałe wyjątki są sprawdzanymi wyjątkami i nie pochodzą one od java.lang.RuntimeException.
Sprawdzone wyjątki : Sprawdzony wyjątek musi zostać wykryty gdzieś w kodzie. Jeśli wywołasz metodę, która zgłasza sprawdzony wyjątek, ale nie złapiesz gdzieś sprawdzonego wyjątku, kod nie zostanie skompilowany. Dlatego nazywane są sprawdzonymi wyjątkami: kompilator sprawdza, czy są obsługiwane lub zadeklarowane.
Wiele metod w Java API rzuca sprawdzone wyjątki, więc często będziesz pisać procedury obsługi wyjątków, aby poradzić sobie z wyjątkami wygenerowanymi przez metody, których nie napisałeś.
źródło
Dlaczego pozwalają na wyjątek? Czy wcześniejsza obsługa błędu nie jest lepsza? Po co bańkować?
Załóżmy na przykład, że masz aplikację typu klient-serwer, a klient wysłał żądanie dotyczące jakiegoś zasobu, którego nie można znaleźć, lub błędu, który mógł wystąpić po stronie serwera podczas przetwarzania żądania użytkownika, więc jest to obowiązek serwera, aby powiedzieć klientowi, dlaczego nie mógł dostać rzeczy, o którą prosił, więc aby to osiągnąć po stronie serwera, kod jest zapisywany w celu wyrzucenia wyjątku za pomocą słowa kluczowego throw zamiast połykania lub obsługi. jeśli serwer obsługuje / połknie to nie będzie szansy na poinformowanie klienta, że wystąpił błąd.
Uwaga: Aby jasno opisać, jaki wystąpił typ błędu, możemy utworzyć własny obiekt wyjątku i przekazać go klientowi.
źródło
Myślę, że sprawdzone wyjątki są dobrym przypomnieniem dla programisty korzystającego z zewnętrznej biblioteki, że w wyjątkowych sytuacjach może dojść do awarii kodu z tej biblioteki.
Przeczytaj więcej na temat sprawdzonych vs niesprawdzonych wyjątków tutaj http://learnjava.today/2015/11/checked-vs-unchecked-exceptions/
źródło
Chcę tylko dodać powód, dla którego w ogóle nie używam sprawdzonych wyjątków. To nie jest pełna odpowiedź, ale czuję, że odpowiada ona na część twojego pytania i uzupełnia wiele innych odpowiedzi.
Ilekroć w grę wchodzą zaznaczone wyjątki,
throws CheckedException
gdzieś w metodzie jest podpis (CheckedException
może to być dowolny sprawdzony wyjątek). Podpis NIE zgłasza wyjątku, zgłaszanie wyjątków jest aspektem implementacji. Interfejsy, podpisy metod, klasy nadrzędne, wszystkie te rzeczy NIE powinny zależeć od ich implementacji. Wykorzystanie sprawdzonych wyjątków tutaj (w rzeczywistości fakt, że musisz zadeklarowaćthrows
w podpisie metody) wiąże twoje interfejsy wyższego poziomu z twoimi implementacjami tych interfejsów.Pokażę ci przykład.
Miejmy ładny i czysty interfejs taki jak ten
Teraz możemy napisać wiele implementacji metody
foo()
, takich jak teKlasa Foo jest w porządku. Teraz zróbmy pierwszą próbę klasy Bar
Bar tej klasy nie będzie się kompilował. Ponieważ wyjątek InterruptedException jest sprawdzonym wyjątkiem, musisz go przechwycić (metodą try-catch wewnątrz metody foo ()) lub zadeklarować, że go zgłaszasz (dodając
throws InterruptedException
do podpisu metody). Ponieważ nie chcę przechwytywać tego wyjątku tutaj (chcę, aby propagował się w górę, aby móc odpowiednio sobie z nim poradzić gdzie indziej), zmieńmy podpis.Bar tej klasy też się nie skompiluje! Metoda baru foo () NIE zastępuje metody IFoo foo (), ponieważ ich podpisy są różne. Mógłbym usunąć adnotację @Override, ale chcę programować przeciwko interfejsowi IFoo like,
IFoo foo;
a później zdecydować, jakiej implementacji chcę użyćfoo = new Bar();
. Jeśli metoda Bar foo () nie przesłania metody foo IFoo, kiedy to zrobięfoo.foo();
nie wywoła implementacji Bar foo ().Aby
public void foo() throws InterruptedException
nadpisać Bar, IFoopublic void foo()
MUSZĄ dodaćthrows InterruptedException
do sygnatury metody IFoo. Spowoduje to jednak problemy z moją klasą Foo, ponieważ sygnatura metody foo () różni się od sygnatury metody IFoo. Ponadto, jeślithrows InterruptedException
dodam do metody Foo foo (), otrzymam kolejny błąd stwierdzający, że metoda Foo foo () deklaruje, że zgłasza InterruptedException, ale nigdy nie zgłasza InterruptedException.Jak widać (gdybym wykonał przyzwoitą robotę tłumacząc te rzeczy), fakt, że rzucam sprawdzony wyjątek, taki jak InterruptedException, zmusza mnie do powiązania mojego interfejsu IFoo z jedną z jego implementacji, co z kolei powoduje spustoszenie w IFoo inne wdrożenia!
Jest to jeden z głównych powodów, dla których sprawdzone wyjątki są ZŁE. W czapki
Jednym z rozwiązań jest przechwycenie zaznaczonego wyjątku, zawinięcie go w niesprawdzony wyjątek i wyrzucenie niesprawdzonego wyjątku.
źródło
throws InterruptedException
do sygnatury metody IFoo bez rzucania czegokolwiek w jakąkolwiek implementację. Więc tak naprawdę nie powoduje żadnego problemu. Jeśli w interfejsie ustawiasz każdą metodę rzucania sygnaturamiException
, daje to po prostu implementacji możliwość rzucenia wyjątku (lub wyjątku, ponieważException
zawiera wszystkie wyjątki).throw Exception
klauzulą w podpisie, nawet jeśli twoja implementacja niczego nie wyrzuci lub może być bardziej szczegółowy wyjątek. Ale nadal czuję, że dobrą praktyką jest zawsze zgłaszanie wyjątku dla metody interfejsu, ponieważ znowu daje to użytkownikowi możliwość rzucania lub nie rzucania czymkolwiek.subclasses
dla klasy,RuntimeException
są niezaznaczone.Exception
ale nieRuntimeException
są uważane zachecked exceptions
.checked exception
.throws
klauzulę zawierającąchecked-exception
.Exception
klasy są definiowane do sprawdzania, gdy są uważane za wystarczająco ważne, aby je złapać lub zadeklarować.źródło
Oto prosta zasada, która może pomóc w podjęciu decyzji. Jest to związane ze sposobem używania interfejsów w Javie.
Weź swoją klasę i wyobraź sobie, że projektujesz dla niej interfejs w taki sposób, aby opisywał on funkcjonalność klasy, ale żadnej implementacji bazowej (tak jak powinien interfejs). Udawaj, że możesz zaimplementować klasę w inny sposób.
Spójrz na metody interfejsu i rozważ wyjątki, które mogą generować:
Jeśli wyjątek może zostać zgłoszony za pomocą metody, niezależnie od podstawowej implementacji (innymi słowy, opisuje tylko funkcjonalność), prawdopodobnie powinien to być sprawdzony wyjątek w interfejsie.
Jeśli wyjątek jest spowodowany przez implementację bazową, nie powinien znajdować się w interfejsie. Dlatego musi to być albo niesprawdzony wyjątek w twojej klasie (ponieważ niesprawdzone wyjątki nie muszą pojawiać się w podpisie interfejsu), albo musisz go owinąć i ponownie zgłosić jako sprawdzony wyjątek, który jest częścią metody interfejsu.
Aby zdecydować, czy należy zawijać i ponownie rzucać, należy ponownie rozważyć, czy użytkownik interfejsu ma natychmiastowe zajęcie się warunkiem wyjątku, czy wyjątek jest tak ogólny, że nie można nic z tym zrobić i należy propaguj stos. Czy zawinięty wyjątek ma sens, gdy wyraża się go jako funkcjonalność nowego interfejsu, który definiujesz, czy jest to po prostu nośnik worek możliwych błędów, które mogą się przytrafić także w przypadku innych metod? Jeśli to pierwsze, może być nadal sprawdzonym wyjątkiem, w przeciwnym razie powinno zostać odznaczone.
Zwykle nie powinieneś planować wyjątków od baniek (łapania i rzucania). Albo wyjątek powinien być obsłużony przez osobę dzwoniącą (w którym to przypadku jest zaznaczone), albo powinien przejść aż do obsługi wysokiego poziomu (w takim przypadku najłatwiej jest, jeśli nie jest zaznaczony).
źródło
Aby zaznaczyć, że jeśli wrzucisz sprawdzony wyjątek do kodu, a połowu jest kilka poziomów powyżej, musisz zadeklarować wyjątek w podpisie każdej metody między tobą a połowem. Tak więc enkapsulacja jest zerwana, ponieważ wszystkie funkcje na ścieżce rzucania muszą wiedzieć o szczegółach tego wyjątku.
źródło
Krótko mówiąc, wyjątki, które moduł lub moduły powyżej mają obsługiwać w czasie wykonywania, nazywane są sprawdzonymi wyjątkami; inni są niesprawdzonych wyjątki, które albo
RuntimeException
alboError
.W tym filmie wyjaśniono sprawdzone i niezaznaczone wyjątki w Javie:
https://www.youtube.com/watch?v=ue2pOqLaArw
źródło
Wszystkie są sprawdzonymi wyjątkami. Niezaznaczone wyjątki to podklasy RuntimeException. Decyzja nie polega na tym, jak sobie z nimi poradzić, należy je wyrzucić. Jeśli nie chcesz, aby kompilator informował Cię, że nie obsłużyłeś wyjątku, użyj niesprawdzonego wyjątku (podklasa RuntimeException). Powinny być zapisane na sytuacje, z których nie można odzyskać, na przykład błędy braku pamięci i tym podobne.
źródło
Jeśli komuś zależy na kolejnym dowodzie, by nie lubić sprawdzonych wyjątków, zobacz kilka pierwszych akapitów popularnej biblioteki JSON:
„Chociaż jest to sprawdzony wyjątek, rzadko można go odzyskać. Większość osób dzwoniących powinna po prostu owinąć ten wyjątek w niesprawdzony wyjątek i ponownie:
Dlaczego więc na świecie ktoś miałby zmuszać deweloperów do sprawdzania wyjątku, skoro zamiast tego powinniśmy go „po prostu owinąć”? lol
http://developer.android.com/reference/org/json/JSONException.html
źródło
Sprawdzone wyjątki :
Wyjątki sprawdzane przez kompilator pod kątem płynnego wykonywania programu w czasie wykonywania są nazywane wyjątkiem sprawdzanym.
Występują one w czasie kompilacji.
Wszystkie podklasy klasy wyjątków, z wyjątkiem RuntimeException, są sprawdzonymi wyjątkami.
Przykład hipotetyczny - Załóżmy, że wychodzisz z domu na egzamin, ale jeśli sprawdzisz, czy wziąłeś Bilet do Hall w domu (czas kompilacji), nie będzie żadnego problemu w Egzaminie (środowisko wykonawcze).
Niezaznaczony wyjątek :
Wyjątki, które nie są sprawdzane przez kompilator, nazywane są Niezaznaczonymi wyjątkami.
Występują one w czasie wykonywania.
Jeśli te wyjątki nie są obsługiwane poprawnie, nie powodują błędu czasu kompilacji. Ale program zostanie przedwcześnie zakończony w czasie wykonywania.
Wszystkie podklasy RunTimeException i Error są niezaznaczonymi wyjątkami.
Przykład hipotetyczny - Załóżmy, że jesteś w sali egzaminacyjnej, ale jakoś szkoła miała wypadek pożarowy (czyli w czasie wykonywania), w którym nie możesz nic zrobić w tym czasie, ale wcześniej można podjąć środki ostrożności (czas kompilacji).
źródło
Wszystkie wyjątki muszą być sprawdzone.
Niezaznaczone wyjątki to nieograniczone gotos. A nieograniczone gotos są uważane za coś złego.
Niezaznaczone wyjątki powodują przerwanie enkapsulacji. Aby je poprawnie przetworzyć, wszystkie funkcje w drzewie połączeń między rzucającym a łapaczem muszą być znane, aby uniknąć błędów.
Wyjątkiem są błędy w funkcji, która je wyrzuca, ale nie błędy w funkcji, która je przetwarza. Wyjątki mają na celu dać programowi drugą szansę poprzez odroczenie decyzji, czy jest to błąd, czy nie, w innym kontekście. Tylko w innym kontekście można podjąć właściwą decyzję.
źródło