Zrozumienie zaznaczonych i niezaznaczonych WYJĄTKÓW w Javie

Joshua Bloch w " Effective Java " powiedział, że

Użyj sprawdzonych wyjątków dla możliwe do odzyskania warunki i czas trwania wyjątki dla błędów programistycznych (Poz. 58 w II wydaniu)

Zobaczmy, czy dobrze to Rozumiem.

Oto moje zrozumienie 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 wyjątek jest uważany za sprawdzony?

2. Czy RuntimeException jest niezaznaczony wyjątek?

Oto moje rozumienie niezaznaczonego 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ć również wyjątkiem sprawdzonym? Mogę spróbować naprawić taką sytuację? Mogę? (Uwaga: moje trzecie pytanie jest wewnątrz 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ą wyjątek bańka up? Czy szybciej nie poradzimy sobie z błędem? Dlaczego bubble up?

6. Czy powinienem dokładnie wyjątek czy maskowanie go za pomocą wyjątku?

Poniżej moje odczyty

W języku Java kiedy należy utworzyć wyjątek sprawdzony, a kiedy powinien to być wyjątek runtime?

Kiedy wybrać wyjątki zaznaczone i niezaznaczone

Author: Yogesh Umesh Vaity, 2011-05-24

21 answers

Wiele osób twierdzi, że zaznaczone wyjątki (tj. te, które należy wyraźnie złapać lub zmienić) nie powinny być w ogóle używane. Zostały one wyeliminowane na przykład w C#, a większość języków ich nie ma. Więc zawsze możesz rzucić podklasę RuntimeException (niezaznaczony wyjątek)

Myślę jednak, że sprawdzone wyjątki są przydatne - są używane, gdy chcesz zmusić użytkownika API do zastanowienia się, jak poradzić sobie z wyjątkową sytuacją (jeśli można ją odzyskać). Po prostu zaznaczone wyjątki są nadużywane na platformie Java, co sprawia, że ludzie ich nienawidzą.

Oto mój Rozszerzony pogląd na temat .

Co do konkretnych pytań:

  1. Czy NumberFormatException rozważa wyjątek sprawdzony?
    Nie. NumberFormatException jest niezaznaczona( = jest podklasą RuntimeException). Dlaczego? Nie wiem. (ale powinna być metoda isValidInteger(..))

  2. Czy RuntimeException jest niezaznaczonym wyjątkiem?
    Tak, dokładnie.

  3. Co powinienem tutaj?
    To zależy od tego, gdzie jest ten kod i co chcesz się wydarzyć. Jeśli jest w warstwie interfejsu-złap go i pokaż ostrzeżenie; jeśli jest w warstwie usługi - nie łap go w ogóle-pozwól mu bańki. Tylko nie przełykaj wyjątku. Jeśli w większości przypadków wystąpi wyjątek, należy wybrać jeden z poniższych:

    • Zaloguj i zwróć
    • rethrow it (declare it to be throwed by the method)
    • zbuduj nowy wyjątek, przekazując bieżący wyjątek w konstruktorze
  4. Czy powyższy kod nie może być również wyjątkiem sprawdzonym? Mogę spróbować naprawić taką sytuację? Mogę?
    Mogło być. Ale nic nie powstrzyma cię również przed złapaniem niezaznaczonego wyjątku

  5. Dlaczego ludzie dodają klasę Exception w klauzuli throws?
    Najczęściej dlatego, że ludzie są leniwi, aby rozważyć, co złapać i co rethrow. Rzucanie Exception jest złą praktyką i powinno być / align = "left" /

Niestety, nie ma jednej reguły pozwalającej określić, kiedy złapać, kiedy rethrow, kiedy użyć sprawdzonych i kiedy użyć niezaznaczonych WYJĄTKÓW. Zgadzam się, że powoduje to wiele zamieszania i dużo złego kodu. Ogólną zasadę podaje Bloch (zacytowałeś jej część). A ogólna zasada jest taka, że trzeba zrobić wyjątek od warstwy, w której można sobie z nią poradzić.

 490
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-30 08:56:13

To ,czy coś jest "zaznaczonym wyjątkiem", nie ma nic wspólnego z tym, czy go złapiesz, czy z tym, co robisz w bloku. To własność klas WYJĄTKÓW. Wszystko, co jest podklasą Exception except for RuntimeException i jego podklasy są wyjątkami sprawdzonymi.

Kompilator Javy wymusza wyłapywanie sprawdzonych wyjątków lub deklarowanie ich w sygnaturze metody. Miało to poprawić bezpieczeństwo programu, ale większość uważa, że nie warto problemy projektowe, które stwarza.

Dlaczego dopuszczają wyjątek w górę? Isnt obsługuje błąd im szybciej lepiej? Dlaczego bubble up?

Ponieważ to jest cały punkt WYJĄTKÓW. Bez tej możliwości nie potrzebowalibyście WYJĄTKÓW. Umożliwiają one obsługę błędów na wybranym poziomie, a nie zmuszają do radzenia sobie z nimi metodami niskopoziomowymi, w których pierwotnie występują.

 242
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-21 22:24:22
  1. Czy powyższe jest uważane za wyjątek sprawdzony? Nie. Fakt, że obsługujesz wyjątek, nie czyni go Checked Exception, jeśli jest RuntimeException.

  2. Czy RuntimeException jest unchecked exception? Tak

Checked Exceptionssubclasses z java.lang.Exception Unchecked Exceptionssubclasses z java.lang.RuntimeException

Wywołania rzucające zaznaczone wyjątki muszą być zamknięte w bloku try{} lub obsługiwane na poziomie powyżej w wywołaniu metody. W takim przypadku obecna metoda musi zadeklarować, że rzuca powiedziane wyjątki, tak aby osoby wywołujące mogły dokonać odpowiednich ustaleń w celu obsługi wyjątku.

Mam nadzieję, że to pomoże.

P: Czy powinienem dokładnie wyjątek czy maskowanie go za pomocą wyjątku?

O: tak jest to bardzo dobre pytanie i ważne rozważenie 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ń go w środku. Ale i duży - Nigdy przenigdy niejasne w podstawowej pierwotnej przyczyny. For ex, Don't ever do following -

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.
}

Zamiast tego wykonaj następujące czynności:

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.
}

Usunięcie pierwotnej przyczyny zakopuje faktyczną przyczynę poza odzyskiwaniem jest koszmarem dla zespołów wsparcia produkcji, gdzie wszystko, do czego mają dostęp, to Dzienniki aplikacji i komunikaty o błędach. Chociaż ten ostatni jest lepszym projektem, ale wiele osób nie używa go często, ponieważ deweloperzy po prostu nie przekazują podstawowej Wiadomości do rozmówcy. Więc zrób notatka firmowa: Always pass on the actual exception z powrotem, niezależnie od tego, czy jest opakowana w wyjątek specyficzny dla aplikacji.

On try-catching RuntimeExceptions

RuntimeExceptions co do zasady nie należy próbować złapać. Zazwyczaj sygnalizują błąd programowania i powinny być pozostawione w spokoju. Zamiast tego programista powinien sprawdzić stan błędu przed wywołaniem kodu, który może spowodować RuntimeException. Dla ex:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welcome to my site!);
} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

To jest zła praktyka programowania. Zamiast tego null-check powinien być wykonany jak -

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

Ale są chwile, kiedy takie sprawdzanie błędów jest drogie, takie jak formatowanie liczb, rozważ to -

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));
} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");
}

Tutaj sprawdzanie błędów wstępnego wywołania nie jest warte wysiłku, ponieważ zasadniczo oznacza powielenie całego kodu konwersji string-to-integer wewnątrz metody parseInt ()-i jest podatne na błędy, jeśli jest zaimplementowane przez programistę. Więc lepiej jest po prostu pozbyć się try-catch.

Więc NullPointerException i NumberFormatException są obie RuntimeExceptions, łapanie NullPointerException powinno zastąpić z gracją null-check, podczas gdy zalecam przechwycenie NumberFormatException jawnie, aby uniknąć ewentualnego wprowadzenia kodu podatnego na błędy.

 76
Author: d-live,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 03:56:13

1 . Jeśli nie masz pewności co do wyjątku, sprawdź API:

 java.lang.Object
 extended by java.lang.Throwable
  extended by java.lang.Exception
   extended by java.lang.RuntimeException  //<-NumberFormatException is a RuntimeException  
    extended by java.lang.IllegalArgumentException
     extended by java.lang.NumberFormatException

2 . Tak, i każdy wyjątek, który go rozszerza.

3 . Nie ma potrzeby, aby złapać i rzucić ten sam wyjątek. W tym przypadku można wyświetlić okno dialogowe nowego pliku.

4 . FileNotFoundException jest już zaznaczonym wyjątkiem.

5 . Jeśli oczekuje się, że metoda wywołująca someMethod, aby złapać wyjątek, ten ostatni może zostać wyrzucony. To po prostu "podaje piłkę". Przykład wykorzystania it byłoby, gdybyś chciał wrzucić go do swoich prywatnych metod, a zamiast tego obsłużyć wyjątek w swojej publicznej metodzie.

Dobrą lekturą jest sam Oracle doc: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Dlaczego projektanci zdecydowali się wymusić metodę, która określi wszystkie nieobciążone, sprawdzone wyjątki, które można wrzucić w jej zakres? Każdy wyjątek, który może być wyrzucony przez metodę, jest częścią publicznego programowania metody interfejs. Ci, którzy wywołują metodę, muszą wiedzieć o wyjątkach, które metoda może rzucać, aby mogli zdecydować, co z nimi zrobić. Wyjątki te są tak samo częścią interfejsu programowania tej metody, jak jej parametry i wartość zwracana.

Następne pytanie może brzmieć: "jeśli tak dobrze jest udokumentować API metody, włączając w to wyjątki, które może ona rzucać, dlaczego nie określić również WYJĄTKÓW runtime?"Wyjątki Runtime reprezentują problemy, które są wynikiem problemu programistycznego, oraz w związku z tym nie można racjonalnie oczekiwać, że kod klienta API odzyska je lub obsłuży w jakikolwiek sposób. Problemy te obejmują wyjątki arytmetyczne, takie jak dzielenie przez zero; wyjątki wskaźnikowe, takie jak próba uzyskania dostępu do obiektu przez odniesienie null; oraz wyjątki indeksujące, takie jak próba uzyskania dostępu do elementu tablicy przez indeks, który jest zbyt duży lub zbyt mały.

Jest też ważna informacja w język Java Specyfikacja:

Klasy WYJĄTKÓW sprawdzonych nazwane w klauzuli throws są częścią umowy pomiędzy wykonawcą a użytkownikiem metody lub konstruktora .

Najważniejsze IMHO jest to, że ty Możesz złapać dowolne RuntimeException, ale nie jesteś do tego zobowiązany i w rzeczywistości implementacja nie jest wymagana do utrzymania tych samych niezabezpieczonych wyjątków, ponieważ nie są one częścią umowy.

 20
Author: Aleadam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

1) nie, wyjątek NumberFormatException jest niezaznaczonym wyjątkiem. Nawet jeśli go złapałeś (nie jesteś zobowiązany), ponieważ jest niezaznaczony. Jest to podklasa IllegalArgumentException, która jest podklasą RuntimeException.

2) RuntimeException jest korzeniem wszystkich niezaznaczonych WYJĄTKÓW. Każda podklasa RuntimeException jest zaznaczona. Wszystkie inne wyjątki i Throwable są sprawdzane z wyjątkiem błędów(które występują pod Throwable).

3/4) możesz zaalarmować użytkownika, że wybrał nieistniejący plik i poprosić o nowy jeden. Lub po prostu przestań informować użytkownika, że wprowadził coś nieprawidłowego.

5) rzucanie i łapanie 'Exception' to zła praktyka. Ale bardziej ogólnie, możesz rzucać inne wyjątki, aby rozmówca mógł zdecydować, jak sobie z tym poradzić. Na przykład, jeśli napisałeś bibliotekę do obsługi odczytu jakiegoś pliku wejściowego, a twoja metoda została przekazana nieistniejącemu plikowi, nie masz pojęcia, jak to zrobić. Dzwoniący chce zapytać ponownie czy zrezygnować? Więc rzucasz wyjątek w górę łańcucha z powrotem do dzwoniący.

W wielu przypadkach występuje unchecked Exception, ponieważ programista nie zweryfikował danych wejściowych (w przypadku NumberFormatException w pierwszym pytaniu). Dlatego jego opcjonalne, aby je złapać, ponieważ istnieją bardziej eleganckie sposoby, aby uniknąć generowania tych wyjątków.

 10
Author: dontocsata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 03:49:50

Sprawdzone - Sprawdzone w czasie kompilacji.

Np.. FileOperations

Niezaznaczone-z powodu złych danych. Sprawdzam czas pracy.

Np..

String s = "abc";
Object o = s;
Integer i = (Integer) o;

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at Sample.main(Sample.java:9)

Tutaj wyjątek wynika ze złych danych i w żaden sposób nie można ich określić podczas kompilacji.

 8
Author: bharanitharan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-24 16:58:37

Zaznaczone wyjątki są sprawdzane podczas kompilacji przez JVM i związane z nim zasoby (pliki / db/stream / socket itp.). Motywem wyjątku checked jest to, że podczas kompilacji, jeśli zasoby nie są dostępne, aplikacja powinna zdefiniować alternatywne zachowanie do obsługi tego w bloku catch/finally.

Niezaznaczone wyjątki to błędy czysto programistyczne, błędne obliczenia, null danych lub nawet awarie logiki biznesowej mogą prowadzić do wyjątków w czasie wykonywania. Jego absolutnie w porządku do obsługa / łapanie niezaznaczonych WYJĄTKÓW w kodzie.

Wyjaśnienie zaczerpnięte z http://coder2design.com/java-interview-questions/

 6
Author: Jatinder Pal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 13:13:19

Mój absolute favorite Opis różnicy między wyjątkami zaznaczonymi i zaznaczonymi znajduje się w artykule Java Tutorial trail, " wyjątki zaznaczone - kontrowersje" (sorry to get all elementary on this post - but, hey, the basics are sometimes the best): {]}

Oto najważniejsze wytyczne: jeśli klient może rozsądnie być oczekuje się, że zostanie odzyskany z wyjątku, uczyni go wyjątkiem sprawdzonym. Jeśli klient nie może nic zrobić, aby odzyskać od wyjątku, uczynić go unchecked exception

Sednem "jakiego typu wyjątek wyrzucić" jest semantyka (w pewnym stopniu) i powyższy cytat zapewnia i doskonałą wytyczną(stąd nadal jestem zdumiony poglądem, że C# pozbył się sprawdzonych WYJĄTKÓW-szczególnie, że Liskov argumentuje o ich przydatności).

Reszta staje się wtedy logiczna: na jakie wyjątki kompilator oczekuje ode mnie wyraźnej odpowiedzi? Te, od których oczekujesz od klienta wyzdrowiej.

 5
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-08 21:21:32

Aby odpowiedzieć na ostatnie pytanie (inni wydają się dokładnie odpowiedzieć powyżej), " Czy powinienem zrobić bańkę z dokładnym wyjątkiem lub zamaskować go za pomocą wyjątku?"

Zakładam, że masz na myśli coś takiego:

public void myMethod() throws Exception {
    // ... something that throws FileNotFoundException ...
}

Nie, zawsze deklaruj najbardziej precyzyjny wyjątek możliwy, lub listę takich. Wyjątki, które deklarujesz jako zdolne do rzucania, są częścią Umowy między Twoją metodą a rozmówcą. Rzucanie "FileNotFoundException" oznacza, że możliwe, że nazwa pliku nie jest poprawny i plik nie zostanie znaleziony; rozmówca będzie musiał to inteligentnie obsłużyć. Rzucanie Exception oznacza: Zgoda."Co jest bardzo ubogim API.

W komentarzach do pierwszego artykułu są przykłady, gdzie" rzuca Exception "jest ważną i rozsądną deklaracją, ale nie jest tak w przypadku większości" normal " kodu, który kiedykolwiek napiszesz.

 5
Author: Tom Dibble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 03:58:54

Wyjątki Runtime : Wyjątki uruchomieniowe są określane jako wyjątki niezaznaczone. Wszystkie inne wyjątki są zaznaczonymi wyjątkami i nie pochodzą z Javy.lang.RuntimeException.

Zaznaczone Wyjątki : Zaznaczony wyjątek musi zostać złapany gdzieś w Twoim kodzie. Jeśli wywołasz metoda, która rzuca zaznaczony wyjątek, ale nie wyłapuje zaznaczonego wyjątku gdzieś Twój Kod się nie skompiluje. Dlatego nazywa się je sprawdzonymi. wyjątki: kompilator sprawdza, czy są obsługiwane lub zadeklarowane.

Wiele metod w API Javy wyrzuca zaznaczone wyjątki, więc często będziesz pisał programy obsługi wyjątków, aby poradzić sobie z wyjątkami generowanymi przez metody, których nie napisałeś.

 5
Author: Omer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-14 14:41:20

Dlaczego dopuszczają wyjątek? Czy szybciej nie poradzimy sobie z błędem? Dlaczego bubble up?

Na przykład powiedzmy, że masz jakąś aplikację Klient-Serwer i klient złożył prośbę o jakiś zasób, którego nie można było znaleźć lub o coś innego błąd, który mógł wystąpić po stronie serwera podczas przetwarzania żądania użytkownika,to obowiązkiem serwera jest powiedzieć klientowi, dlaczego nie mógł uzyskać rzeczy, o którą prosił, więc aby to osiągnąć na serwerze. po stronie serwera, kod jest zapisywany w celu wyrzucenia wyjątku za pomocą słowa kluczowego throw zamiast połykania lub obsługi GO.jeśli serwer ją obsłuży/połknie, wtedy nie będzie szans na poinformowanie klienta, że wystąpił błąd.

Uwaga: aby dokładnie opisać jaki błąd wystąpił, możemy utworzyć własny obiekt Exception i wrzucić go do klienta.

 3
Author: JAVA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-31 18:38:45

Chcę tylko dodać trochę uzasadnienia, aby w ogóle nie używać zaznaczonych WYJĄTKÓW. Nie jest to pełna odpowiedź, ale czuję, że odpowiada na część twojego pytania i uzupełnia wiele innych odpowiedzi.

Ilekroć występują zaznaczone wyjątki, istnieje throws CheckedException gdzieś w sygnaturze metody (CheckedException może być każdy sprawdzony wyjątek). Podpis nie rzuca wyjątku, rzucanie wyjątków jest aspektem implementacji. Interfejsy, podpisy metod, klasy nadrzędne, wszystkie te rzeczy nie powinny zależeć od ich implementacji. Użycie tutaj sprawdzonych WYJĄTKÓW (w rzeczywistości fakt, że musisz zadeklarować throws w podpisie metody) wiąże interfejsy wyższego poziomu z implementacjami tych interfejsów.

Pozwól, że pokażę Ci przykład.

Let ' s have a nice and clean interface like this

public interface IFoo {
    public void foo();
}

Teraz możemy napisać wiele implementacji metody foo(), jak te

public class Foo implements IFoo {
    @Override
    public void foo() {
        System.out.println("I don't throw and exception");
    }
}
Klasa Foo jest w porządku. Teraz zróbmy pierwsza próba na class Bar
public class Bar implements IFoo {
    @Override
    public void foo() {
        //I'm using InterruptedExcepton because you probably heard about it somewhere. It's a checked exception. Any checked exception will work the same.
        throw new InterruptedException();
    }
}

Ten pasek klasy nie będzie kompilowany. Ponieważ InterruptedException jest wyjątkiem zaznaczonym, musisz go przechwycić (za pomocą metody try-catch wewnątrz metody foo ()) lub zadeklarować, że go wyrzucasz (dodając throws InterruptedException do sygnatury metody). Ponieważ nie chcę tutaj przechwytywać tego wyjątku (chcę, aby rozprzestrzeniał się w górę, abym mógł sobie z nim poradzić gdzie indziej), zmieńmy podpis.

public class Bar implements IFoo {
    @Override
    public void foo() throws InterruptedException {
        throw new InterruptedException();
    }
}

Ten pasek klas też się nie skompiluje! Bar ' s method foo() nie nadpisuje metody IFoo foo (), ponieważ ich sygnatury są różne. Mógłbym usunąć adnotację @ Override, ale chcę zaprogramować na interfejsie IFoo jak IFoo foo;, a później zdecydować, której implementacji chcę użyć, jak foo = new Bar();. Jeśli metoda Bar foo () nie nadpisuje metody Foo IFoo, to gdy wykonam foo.foo();, nie wywoła implementacji Foo () Bara.

Aby Bar 's public void foo() throws InterruptedException nadpisać ifoo' s public void foo() muszę dodać throws InterruptedException do podpisu metody IFoo. To jednak spowoduje problemy z moją klasą Foo, ponieważ podpis metody foo () różni się od podpisu metody IFoo. Co więcej, jeśli dodałbym throws InterruptedException do metody Foo foo (), otrzymałbym kolejny błąd stwierdzający, że metoda foo Foo () deklaruje, że wyrzuca przerywaną wyjątek, ale nigdy nie wyrzuca przerywanej wyjątku.

Jak widzisz (jeśli dobrze to wyjaśniłem), fakt, że rzucam sprawdzony wyjątek, taki jak InterruptedException, zmusza mnie do powiązania interfejsu IFoo z jedna z jego implementacji, co z kolei powoduje spustoszenie w innych implementacjach IFoo!

Jest to jeden wielki powód, dla którego zaznaczone wyjątki są złe. W kapslach.

Jednym z rozwiązań jest przechwycenie zaznaczonego wyjątku, zawinięcie go w niezaznaczony wyjątek i wyrzucenie niezaznaczonego wyjątku.

 3
Author: Blueriver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 13:30:47
  • Java rozróżnia dwie kategorie WYJĄTKÓW (zaznaczone i niezaznaczone).
  • Java wymusza wymóg catch lub deklarowany dla sprawdzonych WYJĄTKÓW.
  • typ wyjątku określa, czy wyjątek jest zaznaczony czy niezaznaczony.
  • Wszystkie typy wyjątków, które są bezpośrednie lub pośrednie subclasses klasy RuntimeException są wyjątkami niezaznaczonymi.
  • wszystkie klasy, które dziedziczą z klasy Exception, ale nie RuntimeException są uważane za checked exceptions.
  • klasy, które dziedziczą błąd klasy from jest uważany za niezaznaczony.
  • kompilator sprawdza każde wywołanie i opóźnienie metody w celu ustalenia, czy metoda rzuca checked exception.
    • jeśli tak, kompilator zapewnia, że wyjątek zostanie przechwycony lub zadeklarowany w klauzuli throws.
  • aby spełnić deklarowaną część wymogu catch-or-declare, metoda, która generuje wyjątek musi zawierać klauzulę throws zawierającą checked-exception.
  • Exception klasy są zdefiniowane do sprawdzenia kiedy są uważane za wystarczająco ważne, aby złapać lub zadeklarować.
 3
Author: tokhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-19 06:49:20

Myślę, że zaznaczone wyjątki są dobrym przypomnieniem dla programisty, który korzysta z zewnętrznej biblioteki, że w wyjątkowych sytuacjach może pójść źle z kodem z tej biblioteki.

 3
Author: Dan Moldovan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-11 11:55:34

Oto prosta zasada, która może pomóc ci podjąć decyzję. Jest to związane z tym, jak interfejsy są używane w Javie.

Weź swoją klasę i wyobraź sobie zaprojektowanie dla niej interfejsu tak, aby interfejs opisywał funkcjonalność klasy, ale żadnej z podstawowych implementacji (jak interfejs powinien). Udawaj, że możesz zaimplementować klasę w inny sposób.

Spójrz na metody interfejsu i rozważ wyjątki, które mogą rzucać:

Jeśli wyjątek może być rzucone przez metodę, niezależnie od podstawowej implementacji (innymi słowy, opisuje tylko funkcjonalność), to prawdopodobnie powinien być sprawdzony wyjątek w interfejsie.

Jeśli wyjątek jest spowodowany przez podstawową implementację, nie powinien znajdować się w interfejsie. W związku z tym musi to być albo niezaznaczony wyjątek w twojej klasie (ponieważ niezaznaczone wyjątki nie muszą pojawiać się w sygnaturze interfejsu), albo musisz go zawijać i rethrow jako zaznaczony wyjątek, który jest częścią metody interfejsu.

Aby zdecydować, czy należy zawinąć i rethrow, należy ponownie rozważyć, czy jest sens, aby użytkownik interfejsu musiał natychmiast obsłużyć warunek wyjątku, czy wyjątek jest tak ogólny, że nic nie można z tym zrobić i powinien rozprzestrzeniać się w górę stosu. Czy owinięty wyjątek ma sens, gdy jest wyrażony jako funkcjonalność nowego interfejsu, który definiujesz, czy jest tylko nośnikiem dla worka możliwych błędów, które może się zdarzyć również z innymi metodami? Jeśli pierwszy z nich, nadal może być wyjątkiem zaznaczonym, w przeciwnym razie powinien być odznaczony.

Zazwyczaj nie należy planować" bubble-up " WYJĄTKÓW(catch i rethrow). Albo wyjątek powinien być obsługiwany przez wywołującego (w tym przypadku jest sprawdzany) albo powinien przejść aż do obsługi wysokiego poziomu (w tym przypadku jest to najprostsze, jeśli jest zaznaczone).

 2
Author: rghome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-15 09:45:45

Aby zaznaczyć, że jeśli rzucisz zaznaczony wyjątek w kodzie, a haczyk jest kilka poziomów wyżej, musisz zadeklarować wyjątek w podpisie każdej metody między tobą a haczykiem. Enkapsulacja jest więc przerwana, ponieważ wszystkie funkcje na ścieżce throw muszą wiedzieć o szczegółach tego wyjątku.

 2
Author: Zoran Pandovski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-18 23:09:56

W skrócie, wyjątki, które twój moduł lub powyższe moduły mają obsługiwać podczas wykonywania, nazywane są wyjątkami zaznaczonymi; inne są wyjątkami niezaznaczonymi, które są RuntimeException LUB Error.

W tym filmie wyjaśniono zaznaczone i niezaznaczone wyjątki w Javie:
https://www.youtube.com/watch?v=ue2pOqLaArw

 2
Author: Ozgen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-18 06:19:05

Wszystkie z nich są zaznaczonymi wyjątkami. Niezaznaczone wyjątki są podklasami RuntimeException. Decyzja nie polega na tym, jak sobie z nimi radzić, tylko na tym, czy Twój kod je wyrzuci. Jeśli nie chcesz, aby kompilator informował Cię, że nie obsłużyłeś wyjątku, użyj wyjątku niezaznaczonego (podklasa RuntimeException). Należy je zapisać w sytuacjach, z których nie można odzyskać, takich jak błędy pamięci i tym podobne.

 1
Author: mamboking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-24 19:53:43

Sprawdzone Wyjątki :

  • Wyjątki, które są sprawdzane przez kompilator pod kątem sprawnego wykonania programu w czasie wykonywania, nazywane są wyjątkami sprawdzonymi.

  • Występują one w czasie kompilacji.

  • Je ¶ li nie s ± one obs3ugiwane poprawnie, daj± b3êd czasu kompilacji(nie wyj ± tek).
  • Wszystkie podklasy klasy Exception oprócz RuntimeException są zaznaczonymi wyjątkami.

    Przykład Hipotetyczny - Załóżmy wyjeżdżasz z domu na egzamin, ale jeśli sprawdzisz, czy odebrałeś bilet w domu (czas kompilacji), nie będzie żadnego problemu w sali egzaminacyjnej (runtime).

Unchecked Exception :

  • Wyjątki, które nie są sprawdzane przez kompilator, nazywane są wyjątkami Niezaznaczonymi.

  • Występują one w czasie wykonywania.

  • Jeśli te wyjątki nie są obsługiwane poprawnie, nie powodują błędu w czasie kompilacji. Ale program będzie być przedwcześnie zakończone w czasie wykonywania.

  • Wszystkie podklasy RunTimeException i Error są wyjątkami niezaznaczonymi.

    przykład hipotetyczny - Załóżmy, że jesteś w swojej sali egzaminacyjnej, ale jakoś Twoja szkoła miała wypadek pożarowy (czyli w czasie wykonywania), w którym nie możesz nic zrobić w tym czasie, ale środki ostrożności można zrobić przed (czas kompilacji).

 0
Author: Varun Vashista,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 17:56:17

Jeśli komuś zależy na jeszcze jednym dowodzie niechęci do sprawdzonych WYJĄTKÓW, zobacz kilka pierwszych akapitów popularnej biblioteki JSON:

" chociaż jest to wyjątek sprawdzony, rzadko można go odzyskać. Większość wywołujących powinna po prostu zawinąć ten wyjątek w niezaznaczony wyjątek i napisać: "

Więc dlaczego ktoś miałby zmuszać programistów do sprawdzania wyjątku, skoro zamiast tego powinniśmy "po prostu go zawijać"? lol

Http://developer.android.com/reference/org/json/JSONException.html

 -1
Author: Slawomir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-08 02:58:23

Wszystkie wyjątki muszą być zaznaczonymi wyjątkami.

  1. Niezaznaczone wyjątki to nieograniczone Goto. A nieograniczone Goto są uważane za złą rzecz.

  2. Niezaznaczone wyjątki przerywają enkapsulację. Aby je poprawnie przetworzyć, wszystkie funkcje w drzewie wywołań między miotaczem a łapaczem muszą być znane, aby uniknąć błędów.

  3. Wyjątkami są błędy w funkcji, która je rzuca, ale nie błędy w funkcji, która je przetwarza. Celem wyjątkami jest danie programowi drugiej szansy poprzez odroczenie decyzji, czy jest to błąd, czy nie, do innego kontekstu. Tylko w innym kontekście można podjąć właściwą decyzję.

 -2
Author: shawnhcorey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-01 12:36:08