Kiedy wybrać wyjątki zaznaczone i niezaznaczone

W Javie (lub innym języku z zaznaczonymi wyjątkami), jak podczas tworzenia własnej klasy WYJĄTKÓW zdecydować, czy powinna być zaznaczona czy odznaczona?

Moim instynktem jest stwierdzenie, że sprawdzony wyjątek będzie wywoływany w przypadkach, w których rozmówca może być w stanie odzyskać w jakiś produktywny sposób, gdzie jako niezaznaczony wyjątek byłby bardziej dla nieodwracalnych przypadków, ale byłbym zainteresowany cudzymi przemyśleniami.

Author: Josh Lee, 2008-08-26

18 answers

Zaznaczone wyjątki są świetne, o ile rozumiesz, kiedy powinny być używane. Java core API nie przestrzega tych reguł dla SQLException (a czasami dla IOException), dlatego są one tak straszne.

Zaznaczone wyjątki powinny być używane dla przewidywalnych , ale niewyrażalnych błędów, które są rozsądne do odzyskania z .

Niezaznaczone wyjątki powinny być używane do wszystkiego innego.

Rozbiję to na ty, ponieważ większość ludzi źle rozumie, co to znaczy.

  1. przewidywalne, ale niemożliwe do przewidzenia : wywołujący zrobił wszystko, co w ich mocy, aby zweryfikować parametry wejściowe, ale niektóre warunki poza ich kontrolą spowodowały niepowodzenie operacji. Na przykład próbujesz odczytać plik, ale ktoś usuwa go między czasem sprawdzenia, czy istnieje, a czasem rozpoczęcia operacji odczytu. Deklarując zaznaczony wyjątek, każesz rozmówcy przewidzieć ten porażka.
  2. rozsądne do odzyskania od: nie ma sensu nakazywać dzwoniącym przewidywania wyjątków, od których nie mogą odzyskać. Jeśli użytkownik spróbuje odczytać plik z nieistniejącego pliku, wywołujący może poprosić go o nową nazwę pliku. Z drugiej strony, jeśli metoda zawiedzie z powodu błędu programistycznego (nieprawidłowe argumenty metody lub błędna implementacja metody), aplikacja nie może nic zrobić, aby rozwiązać problem w trakcie wykonywania. Najlepsze, co może zrobić, to zarejestrować problem i czekać dla programisty, aby naprawić go w późniejszym czasie.

O ile wyjątek, który rzucasz, nie spełnia wszystkich powyższych warunków, należy użyć wyjątku niezaznaczonego.

Reevaluate na każdym poziomie: czasami metoda wyłapująca zaznaczony wyjątek nie jest właściwym miejscem do obsługi błędu. W takim przypadku rozważ, co jest rozsądne dla własnych rozmówców. Jeśli wyjątek jest przewidywalny, nie do przewidzenia i rozsądny, aby odzyskać od tego powinieneś rzucić sam sprawdź wyjątek. Jeśli nie, należy zawinąć wyjątek w niezaznaczony wyjątek. Jeśli zastosujesz się do tej zasady, przekonwertujesz zaznaczone wyjątki na niezaznaczone wyjątki i odwrotnie, w zależności od tego, na jakiej warstwie się znajdujesz.

Dla WYJĄTKÓW zaznaczonych i niezaznaczonych, użyj właściwego poziomu abstrakcji . Na przykład repozytorium kodu z dwiema różnymi implementacjami (bazą danych i systemem plików) powinno unikać ujawniania szczegółów specyficznych dla implementacji przez rzucanie SQLException LUB IOException. Zamiast tego należy zawinąć wyjątek w abstrakcję, która obejmuje wszystkie implementacje (np. RepositoryException).

 177
Author: Gili,
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-05-03 16:25:55

From A Java Learner :

Gdy wystąpi wyjątek, musisz albo Złap i obsłuż wyjątek, albo powiedz kompilatorowi, że nie możesz sobie poradzić to deklarując, że twoja metoda rzuca ten wyjątek, a następnie kod który używa Twojej metody będzie musiał obsługi tego wyjątku (nawet to także może zdecydować się na zadeklarowanie, że rzuca wyjątek, jeśli nie może sobie z tym poradzić).

Kompilator sprawdzi, czy zrobiliśmy jedną z dwóch rzeczy (złapać, czy declare). Tak więc nazywa się je sprawdzonymi wyjątki. Ale błędy i Runtime Wyjątki nie są sprawdzane przez kompilatora (chociaż można wybrać złapać lub zadeklarować, że nie jest wymagane). Więc te dwa są nazywane Niezaznaczone wyjątki.

Błędy są używane do reprezentowania tych warunki, które występują poza aplikacji, takich jak crash of the system. Wyjątkami Runtime są zwykle występują z winy w logika aplikacji. You can ' t do wszystko w tych sytuacje. Kiedy wystąpił wyjątek runtime, musisz przepisz kod programu. Więc te nie są sprawdzane przez kompilator. Te wyjątki uruchomieniowe zostaną ujawnione w rozwój i okres testowania. Wtedy musimy refaktorować nasz kod, aby usunąć te błędy.

 52
Author: Espo,
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
2008-08-26 08:51:27

Zasada, której używam to: nigdy nie używaj niezaznaczonych WYJĄTKÓW! (lub gdy nie widzisz żadnego sposobu na obejście)

Jest bardzo silny argument przeciwny: nigdy nie używaj sprawdzonych WYJĄTKÓW. Niechętnie biorę udział w debacie, ale wydaje się, że istnieje szeroki konsensus, że wprowadzenie sprawdzonych WYJĄTKÓW było błędną decyzją z perspektywy czasu. Proszę nie strzelać do posłańca i odwoływać się do tych argumenty .

 45
Author: Konrad Rudolph,
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
2008-08-26 09:30:18

Na każdym wystarczająco dużym systemie, z wieloma warstwami, zaznaczone wyjątki są bezużyteczne, ponieważ w każdym razie potrzebujesz strategii na poziomie architektonicznym, aby poradzić sobie z tym, jak wyjątek będzie obsługiwany (użyj bariery błędu)

Z zaznaczonymi wyjątkami twój stan obsługi błędów jest mikro-zarządzany i nie do zniesienia w każdym dużym systemie.

Przez większość czasu nie wiesz, czy błąd jest "możliwy do odzyskania", ponieważ nie wiesz, w jakiej warstwie znajduje się Wywoływacz twojego API.

Powiedzmy, że ja Utwórz API StringToInt, które konwertuje reprezentację ciągu znaków liczby całkowitej na liczbę Int. Czy muszę rzucać zaznaczony wyjątek, jeśli API jest wywoływane z ciągiem "foo"? Można go odzyskać ? Nie wiem, bo w jego warstwie wywołujący mój StringToInt API może już zweryfikować dane wejściowe, a jeśli ten wyjątek zostanie wyrzucony, to albo błąd, albo uszkodzenie danych i nie można go odzyskać dla tej warstwy.

W tym przypadku wywołujący API nie chce wychwycić wyjątku. On chce, aby wyjątek"bubble up". Jeśli wybrałem zaznaczony wyjątek, ten rozmówca będzie miał mnóstwo bezużytecznego bloku catch tylko po to, aby sztucznie zmienić wyjątek.

To, co można odzyskać, zależy w większości przypadków od wywołującego API, a nie od Writera API. Interfejs API nie powinien używać WYJĄTKÓW zaznaczonych, ponieważ tylko wyjątki niezaznaczone pozwalają wybrać opcję przechwytywania lub ignorowania wyjątku.

 35
Author: Stephane,
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
2008-09-17 21:25:03

Masz rację.

Niezaznaczone wyjątki są używane, aby pozwolić systemowi szybko zawieść , co jest dobrą rzeczą. Powinieneś jasno określić, czego oczekuje twoja metoda, aby działać prawidłowo. W ten sposób można zweryfikować dane wejściowe tylko raz.

Na przykład:

/**
 * @params operation - The operation to execute.
 * @throws IllegalArgumentException if the operation is "exit"
 */
 public final void execute( String operation ) {
     if( "exit".equals(operation)){
          throw new IllegalArgumentException("I told you not to...");
     }
     this.operation = operation; 
     .....  
 }
 private void secretCode(){
      // we perform the operation.
      // at this point the opreation was validated already.
      // so we don't worry that operation is "exit"
      .....  
 }
Żeby dać przykład. Chodzi o to, że jeśli system szybko zawiedzie, będziesz wiedział, gdzie i dlaczego nie. Dostaniesz stacktrace jak:
 IllegalArgumentException: I told you not to use "exit" 
 at some.package.AClass.execute(Aclass.java:5)
 at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
 ar ......
I będziesz wiedział, co się stało. Druga klasa w metodzie "delegateTheWork" (w linii 4569 ) wywołała Twoją klasę z wartością "exit", nawet jeśli nie powinna itd.

W Przeciwnym Razie musiałbyś posypać walidacje całym kodem i to jest podatne na błędy. Ponadto czasami trudno jest śledzić, co poszło nie tak i możesz spodziewać się godzin frustrującego debugowania]}

To samo dzieje się z NullPointerExceptions. Jeśli masz klasę 700 linii z 15 metodami, która używa 30 atrybutów i żadna z nich nie może być null, zamiast walidacji w każdej z tych metod dla nullability można zrobić wszystkie te atrybuty tylko do odczytu i zweryfikować je w konstruktorze lub metodzie fabrycznej.

 public static MyClass createInstane( Object data1, Object data2 /* etc */ ){ 
      if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }

  }


  // the rest of the methods don't validate data1 anymore.
  public void method1(){ // don't worry, nothing is null 
      ....
  }
  public void method2(){ // don't worry, nothing is null 
      ....
  }
  public void method3(){ // don't worry, nothing is null 
      ....
  }

Zaznaczone wyjątki są przydatne, gdy programista (ty lub twoi współpracownicy ) zrobił wszystko dobrze, zweryfikował dane wejściowe, przeprowadził testy i cały kod jest idealny, ale kod łączy się z zewnętrznym serwisem internetowym, który może być wyłączony ( lub plik, którego używałeś, został usunięty przez inny zewnętrzny proces itp ) . Webservice może nawet zostać zweryfikowany przed próbą połączenia, ale podczas transferu danych coś poszło nie tak.

W tym scenariuszu nie ma nic, co Ty lub twoi współpracownicy mogą zrobić, aby mu pomóc. Ale nadal musisz coś zrobić i nie pozwolić aplikacji po prostu umrzeć i zniknąć w oczach użytkownika. Używasz do tego wyjątku sprawdzonego i obsługujesz ten wyjątek, co możesz zrobić, gdy tak się stanie?, przez większość czasu, tylko po to, aby spróbować zalogować błąd, prawdopodobnie zapisać swojej pracy (praca aplikacji) i przedstawić wiadomość użytkownikowi. (Strona blabla jest wyłączona, spróbuj ponownie później itp. )

Jeśli zaznaczony wyjątek jest nadużywany (dodając "throw Exception" we wszystkich podpisach metod), wtedy twój kod stanie się bardzo delikatny, ponieważ każdy zignoruje ten wyjątek ( ponieważ jest zbyt ogólny ) i jakość kodu będzie poważnie zagrożona.

Jeśli nadużywasz niezaznaczonego wyjątku, stanie się coś podobnego. Użytkownicy ten kod Nie wiem, czy coś może pójść nie tak wiele spróbować{...} catch( Throwable t ) pojawi się.

 26
Author: OscarRyz,
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
2008-11-27 03:49:46

Oto moja "ostateczna zasada".
Używam:

  • unchecked exception w kodzie mojej metody na awarię spowodowaną wywołaniem (która obejmujejednoznaczna i kompletna dokumentacja)
  • sprawdzony wyjątek dla awarii z powodu callee że muszę wyraźnie powiedzieć każdemu, kto chce użyć mojego kodu

W porównaniu z poprzednią odpowiedzią, jest to jasne uzasadnienie (na którym może się zgodzić lub nie zgodzić) na użycie jednego lub drugiego (lub obu) rodzaju WYJĄTKÓW.


Dla obu tych wyjątków, stworzę własny wyjątek zaznaczony i zaznaczony dla mojej aplikacji (dobra praktyka, Jak wspomniano tutaj), z wyjątkiem bardzo częstego wyjątku zaznaczonego (jak NullPointerException)

Więc na przykład, celem tej konkretnej funkcji poniżej jest uczynienie (lub uzyskanie, jeśli już istnieje) obiektu,
Znaczenie:

  • pojemnik z obiekt make / get musi istnieć (odpowiedzialność wywołującego
    = > niezaznaczony wyjątek i wyczyść komentarz javadoc dla tej wywołanej funkcji)
  • inne parametry nie mogą być null
    (wybór kodera, aby umieścić go na wywołującym: koder nie sprawdzi parametru null, ale koder go udokumentuje)
  • wynik nie może być NULL
    (odpowiedzialność i wybór kodu dzwoniącego, wybór, który będzie bardzo interesujący dla dzwoniącego
    => zaznaczony wyjątek ponieważ każdy wywołujący musi podjąć decyzję, jeśli obiekt nie może zostać utworzony/znaleziony, a decyzja ta musi być egzekwowana w czasie kompilacji: nie mogą korzystać z tej funkcji bez konieczności radzenia sobie z tą możliwością, czyli z tym zaznaczonym wyjątkiem).

Przykład:


/**
 * Build a folder. <br />
 * Folder located under a Parent Folder (either RootFolder or an existing Folder)
 * @param aFolderName name of folder
 * @param aPVob project vob containing folder (MUST NOT BE NULL)
 * @param aParent parent folder containing folder 
 *        (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
 * @param aComment comment for folder (MUST NOT BE NULL)
 * @return a new folder or an existing one
 * @throws CCException if any problems occurs during folder creation
 * @throws AssertionFailedException if aParent is not in the same PVob
 * @throws NullPointerException if aPVob or aParent or aComment is null
 */
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
    final IPVob aPVob, final Comment aComment) throws CCException {
    Folder aFolderRes = null;
    if (aPVob.equals(aParent.getPVob() == false) { 
       // UNCHECKED EXCEPTION because the caller failed to live up
       // to the documented entry criteria for this function
       Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }

    final String ctcmd = "mkfolder " + aComment.getCommentOption() + 
        " -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);

    final Status st = getCleartool().executeCmd(ctcmd);

    if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
        aFolderRes = Folder.getFolder(aFolderName, aPVob);
    }
    else {
        // CHECKED EXCEPTION because the callee failed to respect his contract
        throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
    }
    return aFolderRes;
}
 17
Author: VonC,
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
2017-05-23 12:10:43

To nie tylko kwestia możliwości odzyskania od wyjątku. Najważniejsze, moim zdaniem, jest to, czy rozmówca jest zainteresowany złapaniem wyjątku, czy nie.

Jeśli piszesz bibliotekę, która ma być używana gdzie indziej, lub warstwę niższego poziomu w Twojej aplikacji, zadaj sobie pytanie, czy wywołujący jest zainteresowany wyłapaniem (poznaniem) twojego wyjątku. Jeśli tak nie jest, użyj niekontrolowanego wyjątku, aby nie obciążać go niepotrzebnie.

Jest to filozofia używana przez wielu ramy. W szczególności przychodzą na myśl Spring i hibernate - konwertują znany wyjątek zaznaczony na wyjątek zaznaczony właśnie dlatego, że wyjątki zaznaczone są nadużywane w Javie. Jednym z przykładów, który mogę wymyślić jest JSONException z json.org, co jest zaznaczonym wyjątkiem i jest w większości denerwujące - powinno być odznaczone, ale programista po prostu tego nie przemyślał.

Nawiasem mówiąc, w większości przypadków zainteresowanie wywołującego wyjątkiem jest bezpośrednio skorelowane z możliwość odzyskania od wyjątku, ale nie zawsze tak jest.

 15
Author: Yoni,
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
2008-11-27 02:29:08

Oto bardzo proste rozwiązanie twojego dylematu.

Reguła 1: pomyśl o Niezaznaczonym wyjątku jako warunku testowalnym przed wykonaniem kodu. na przykład ...

x.doSomething(); // the code throws a NullPointerException

Gdzie x jest null... ... kod powinien mieć następujące ...

if (x==null)
{
    //do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
    x = new X();
}
x.doSomething();

Reguła 2: pomyśl o sprawdzonym wyjątku jako o stanie niemożliwym do przetestowania, który może wystąpić podczas wykonywania kodu.

Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

... w powyższym przykładzie URL (google.com) może być niedostępny ze względu na to, że serwer DNS jest na ziemię. Nawet w momencie, gdy serwer DNS działał i rozwiązał "google.com" nazwa na adres IP, jeżeli połączenie jest wykonane z google.com, w każdej chwili po słowie, sieć może ulec awarii. Po prostu nie można testować sieci cały czas przed czytaniem i pisaniem do strumieni.

Są chwile, kiedy Kod po prostu musi zostać wykonany, zanim dowiemy się, czy jest jakiś problem. Zmuszając programistów do pisania kodu w taki sposób, aby zmusić ich do radzenia sobie z tymi sytuacjami poprzez sprawdzanie Wyjątek, muszę przyznać, że twórca Javy wymyślił tę koncepcję.

Ogólnie rzecz biorąc, prawie wszystkie API w Javie są zgodne z powyższymi 2 zasadami. Jeśli spróbujesz zapisać do pliku, dysk może się zapełnić przed zakończeniem zapisu. Możliwe, że inne procesy spowodowały zapełnienie dysku. Po prostu nie ma sposobu, aby przetestować tę sytuację. Dla tych, którzy wchodzą w interakcję ze sprzętem, gdzie w dowolnym momencie korzystanie ze sprzętu może się nie udać, sprawdzone wyjątki wydają się eleganckie rozwiązanie tego problemu.

Jest w tym szara strefa. W przypadku, gdy potrzeba wielu testów (zdumiewające stwierdzenie if z dużą ilością & & i//), wyjątek rzucony będzie CheckedException po prostu dlatego, że jest to zbyt wiele bólu, aby uzyskać prawo - po prostu nie można powiedzieć, że ten problem jest błąd programowania. Jeśli jest znacznie mniej niż 10 testów (np. ' if (X = = null)'), to błąd programisty powinien być Niecheckedexception.

Rzeczy stają się interesujące, gdy mamy do czynienia z Tłumacze języka. Zgodnie z powyższymi zasadami, czy błąd składni należy uznać za zaznaczony lub niezaznaczony wyjątek? Argumentowałbym, że jeśli składnia języka może zostać przetestowana przed jego wykonaniem, powinno to być UncheckedException. Jeśli język nie może być testowany - podobnie jak kod assembly działa na komputerze osobistym, wtedy błąd składni powinien być wyjątkiem Checked.

Powyższe 2 Zasady prawdopodobnie usuną 90% Twojego problemu, który możesz wybrać. Na podsumuj Zasady, postępuj zgodnie z tym wzorem… 1) jeśli kod do wykonania może zostać przetestowany przed jego wykonaniem, aby działał poprawnie i jeśli wystąpi wyjątek-znany jako błąd programisty, wyjątek powinien być UncheckedException (podklasa RuntimeException). 2) jeśli kod do wykonania nie może zostać przetestowany przed jego wykonaniem, aby działał poprawnie, wyjątek powinien być wyjątkiem sprawdzonym (podklasa wyjątku).

 9
Author: user3598189,
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-05-03 02:58:15

Można nazwać wyjątek zaznaczony lub niezaznaczony; jednak oba typy WYJĄTKÓW mogą być przechwycone przez programistę, więc najlepszą odpowiedzią jest: zapisz wszystkie swoich WYJĄTKÓW jako niezaznaczone i udokumentuj je. W ten sposób programista, który korzysta z twojego API, może wybrać, czy chce złapać ten wyjątek i coś zrobić. Zaznaczone wyjątki to kompletna strata czasu wszystkich i sprawia, że Twój kod jest szokującym koszmarem do oglądania. Właściwe testy jednostkowe będą następnie wprowadź wszelkie wyjątki, które możesz złapać i coś z nimi zrobić.

 8
Author: Colin Saxton,
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-11-16 21:15:33

Zaznaczony Wyjątek: Jeśli klient może odzyskać wyjątek i chce kontynuować, użyj zaznaczonego wyjątku.

Unchecked Exception: Jeśli klient nie może zrobić nic po tym wyjątku, podnieś zaznaczony wyjątek.

Przykład: jeśli oczekuje się wykonania operacji arytmetycznej w metodzie a() i w oparciu o wynik z a (), należy wykonać inną operację. Jeśli wynik jest null z metody a (), której nie spodziewasz się w czasie wykonywania, to oczekuje się, że rzucisz wyjątek wskaźnika Null, który jest wyjątkiem czasu pracy.

Poleć tutaj

 6
Author: challenger,
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-19 01:05:14

Zgadzam się z preferencją dla niezaznaczonych WYJĄTKÓW jako reguły, szczególnie przy projektowaniu API. Rozmówca może zawsze wybrać przechwycenie udokumentowanego, niezaznaczonego wyjątku. Nie zmuszasz do tego rozmówcy.

Uważam, że zaznaczone wyjątki są przydatne na niższym poziomie, jako szczegóły implementacji. Często wydaje się to lepszym mechanizmem sterowania niż konieczność zarządzania określonym błędem "kodu zwrotnego". Czasem może pomóc dostrzec wpływ pomysłu na niski poziom zmiana kodu też... zadeklaruj zaznaczony wyjątek i sprawdź, kto będzie musiał go dostosować. Ten ostatni punkt nie ma zastosowania, jeśli istnieje wiele generycznych: catch (Exception e) lub wyrzuca wyjątek , Który i tak zwykle nie jest zbyt dobrze przemyślany.

 2
Author: Scott Kurz,
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
2013-03-24 18:47:04

Oto chcę podzielić się swoją opinią, którą mam po wielu latach doświadczenia w rozwoju:

  1. Zaznaczony wyjątek. Jest to część business use case lub call flow, jest to część logiki aplikacji, której oczekujemy lub nie oczekujemy. Na przykład połączenie odrzucone, warunek nie jest spełniony itp. Musimy to obsłużyć i pokazać odpowiednią wiadomość użytkownikowi z instrukcjami, co się stało i co zrobić dalej (spróbuj ponownie później itp.). Zwykle nazywam to wyjątkiem post-processing lub " użytkownik" wyjątek.

  2. Niezaznaczony wyjątek. Jest to część wyjątku programistycznego, jakiś błąd w programowaniu kodu oprogramowania (błąd, defekt) i odzwierciedla sposób, w jaki programiści muszą używać API zgodnie z dokumentacją. JeĹ " li zewnÄ ™ trzny dokument lib/framework mówi, Ĺźe spodziewa siÄ ™ otrzymaÄ ‡ dane w pewnym zakresie i nie null, poniewaĹź NPE lub IllegalArgumentException bÄ ™ dzie wyrzucane, programista powinien tego oczekiwaÄ ‡ i uĺźywaä ‡ API poprawnie zgodnie z dokumentacjÄ.... W przeciwnym razie wyjątek zostanie wyrzucony. Zwykle to nazywam wyjątek przetwarzania wstępnego lub wyjątek "Walidacja".

Według grupy docelowej. Teraz porozmawiajmy o grupie docelowej lub grupie osób wyjątki zostały zaprojektowane (zgodnie z moją opinią):

  1. zaznaczony wyjątek. Grupa docelowa to użytkownicy / klienci.
  2. niezaznaczony wyjątek. Grupa docelowa to deweloperzy. Innymi słowy, niezaznaczone wyjątki są przeznaczone tylko dla programistów.

Według fazy cyklu życia aplikacji.

  1. sprawdzone wyjątek ma na celu istnienie podczas całego cyklu życia produkcji jako normalnego i oczekiwanego mechanizmu aplikacja obsługuje wyjątkowe przypadki.
  2. niezaznaczony wyjątek jest zaprojektowany tak, aby istniał tylko podczas cyklu rozwoju/testowania aplikacji, wszystkie z nich powinny być naprawione w tym czasie i nie powinny być wyrzucane, gdy aplikacja jest już uruchomiona na produkcji.

Powodem, dla którego frameworki zwykle używają niezaznaczonych WYJĄTKÓW (na przykład Spring) jest to, że framework nie może określ logikę biznesową aplikacji, to zależy od programistów, aby złapać następnie i zaprojektować własną logikę.

 2
Author: Denys,
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
2017-06-30 15:34:29

Zaznaczone wyjątki są przydatne w przypadkach, w których chcesz przekazać informacje wywołującemu (np. niewystarczające uprawnienia, plik nie znaleziony, itp.).

Niezaznaczone wyjątki są używane rzadko, jeśli w ogóle, do informowania użytkownika lub programisty o poważnych błędach lub nieoczekiwanych warunkach podczas pracy. Nie wyrzucaj ich, jeśli piszesz kod lub biblioteki, które będą używane przez inne osoby, ponieważ mogą nie oczekiwać, że Twoje oprogramowanie wyrzuci niezaznaczone wyjątki od czasu kompilatora nie zmusza ich do bycia złapanymi ani ogłoszonymi.

 1
Author: David Crow,
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
2008-08-26 09:13:07

Jeśli wyjątek jest mniej prawdopodobny i możemy postępować nawet po jego wyłapaniu, a nie możemy zrobić nic, aby go uniknąć, możemy użyć wyjątku sprawdzonego.

Gdy chcemy zrobić coś znaczącego, gdy wystąpi konkretny wyjątek i gdy ten wyjątek jest oczekiwany, ale nie pewny, możemy użyć wyjątku sprawdzonego.

Ilekroć wyjątek poruszający się w różnych warstwach, nie musimy go łapać w każdej warstwie, w takim przypadku możemy użyć wyjątek runtime lub wyjątek zawijania jako wyjątek niezaznaczony.

Exception Runtime jest używany, gdy wyjątek najprawdopodobniej się wydarzy, nie ma możliwości pójścia dalej i nic nie można odzyskać. Tak więc w tym przypadku możemy podjąć środki ostrożności w odniesieniu do tego wyjątku. EX: NUllPointerException, ArrayOutofBoundsException. Są one bardziej prawdopodobne. W tym scenariuszu możemy podjąć środki ostrożności podczas kodowania, aby uniknąć takiego wyjątku. W przeciwnym razie będziemy musieli napisać spróbuj złapać bloki co gdzie

Bardziej ogólne wyjątki mogą być wyłączone, mniej ogólne są zaznaczone.

 1
Author: ramu p,
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-02-06 09:29:10

Myślę, że możemy pomyśleć o wywodach z kilku pytań:

Dlaczego exeption się dzieje? Co możemy zrobić, gdy to się stanie

Przez pomyłkę, robal. np. wywołana jest metoda obiektu null.

String name = null;
... // some logics
System.out.print(name.length()); // name is still null here

Ten rodzaj wyjątku powinien być ustalony podczas badania. W przeciwnym razie, przerywa produkcję i masz bardzo wysoki błąd, który musi zostać natychmiast naprawiony. Tego rodzaju wyjątki nie muszą być sprawdzane.

Przez wejście z zewnątrz, nie można kontrolować ani ufać wyjściom usług zewnętrznych.

String name = ExternalService.getName(); // return null
System.out.print(name.length());    // name is null here

Tutaj może być konieczne sprawdzenie, czy nazwa jest null, jeśli chcesz kontynuować, gdy jest null, w przeciwnym razie możesz zostawić ją w spokoju i zatrzyma się tutaj i dać wywołującemu wyjątek runtime. Tego rodzaju wyjątki nie muszą być sprawdzane.

Przez exception runtime from external, nie można kontrolować ani ufać zewnętrznej usłudze.

Tutaj może być konieczne wyłapanie wszystkich wyjątków od ExternalService jeśli chcesz kontynuować, gdy to się stanie, w przeciwnym razie możesz zostawić to w spokoju i zatrzyma się tutaj i dać wywołującemu wyjątek runtime.

Przez zaznaczony wyjątek od external, nie można kontrolować ani ufać zewnętrznej usłudze.

Tutaj może być konieczne wyłapanie wszystkich wyjątków z ExternalService, jeśli chcesz kontynuować, gdy to się stanie, w przeciwnym razie możesz zostawić to w spokoju i zatrzyma się tutaj i dać wywołującemu wyjątek runtime.

W czy w tym przypadku musimy wiedzieć, jaki wyjątek miał miejsce w ExternalService? to zależy:

  1. Jeśli możesz obsłużyć niektóre rodzaje WYJĄTKÓW, musisz je złapać i przetworzyć. Dla innych, bubble je.

  2. Jeśli potrzebujesz logu lub odpowiedzi na konkretne wykonanie użytkownika, możesz je złapać. Dla innych, bubble je.

 1
Author: Jacky,
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-10-16 10:06:18

Myślę, że podczas deklarowania wyjątku aplikacji powinien być on niezaznaczony, np. podklasa RuntimeException. Powodem jest to, że nie będzie zaśmiecać kodu aplikacji za pomocą metody try-catch i throws declaration on. Jeśli Twoja aplikacja używa Java Api, które wyświetla zaznaczone wyjątki, które i tak muszą być obsługiwane. W innych przypadkach aplikacja może wyrzucić niezaznaczony wyjątek. Jeśli wywołujący aplikację nadal musi obsługiwać niezaznaczony wyjątek, można to zrobić.

 0
Author: Akash Aggarwal,
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
2017-05-09 15:21:40

Musimy rozróżnić te dwa typy WYJĄTKÓW na podstawie tego, czy jest to błąd programisty, czy nie.

  • Jeśli błąd jest błędem programisty, musi to być niezaznaczony wyjątek . na przykład: SQLException/IOException / NullPointerException. Wyjątki te to błędy programowania. Powinny być obsługiwane przez programistę. Podczas gdy w JDBC API, SqlException jest zaznaczonym wyjątkiem, wiosną JDBCTemplate jest to niezaznaczony wyjątek.Programista się nie martwi o firmie SqlException, gdy używasz sprężyny.
  • Jeśli błąd nie jest błędem programisty, a przyczyna pochodzi z zewnątrz, musi to być wyjątek sprawdzony. na przykład: jeśli plik jest usuwany lub uprawnienia do pliku są zmieniane przez kogoś innego, to powinien być odzyskany.

FileNotFoundException jest dobrym przykładem do zrozumienia subtelnych różnic. FileNotFoundException jest wrzucany w przypadku, gdy plik nie został znaleziony. Istnieją dwa powody tego wyjątku. Jeśli ścieżka do pliku jest zdefiniowany przez programistę lub pobrany od użytkownika końcowego przez GUI powinien być Niezaznaczonym wyjątkiem. Jeśli plik zostanie usunięty przez inną osobę, powinien to być wyjątek sprawdzony.

Zaznaczony wyjątek może być obsługiwany na dwa sposoby. Używają wyjątku try-catch lub propagate. W przypadku propagacji WYJĄTKÓW, wszystkie metody w stosie wywołań będą ściśle powiązane ze względu na obsługę wyjątków. Dlatego musimy ostrożnie używać sprawdzonych WYJĄTKÓW.

W przypadku wystąpienia warstwowy system korporacyjny, musisz wybrać głównie niezaznaczony wyjątek do rzucania, ale nie zapomnij użyć zaznaczonego wyjątku w przypadku, gdy nie możesz nic zrobić.

 0
Author: ailhanli,
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-07-27 14:46:35

Zasada, której używam to: nigdy nie używaj niezaznaczonych WYJĄTKÓW! (lub gdy nie widzisz żadnego sposobu na obejście)

Z punktu widzenia programisty używającego twojej Biblioteki lub użytkownika końcowego używającego Twojej biblioteki / aplikacji jest naprawdę do bani skonfrontować się z aplikacją, która ulega awarii z powodu nieoznaczonego wyjątku. I liczenie na połów-wszystko też nie jest dobre.

W ten sposób użytkownik końcowy może nadal otrzymywać komunikat o błędzie, zamiast całkowicie znikać z aplikacji.

 -12
Author: ,
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
2008-08-26 09:19:11