Jest kilka zasad postępowania z wyjątkami, o których należy pamiętać. Ale najpierw musisz pamiętać, że wyjątki są częścią interfejsu ujawnionego przez kod; udokumentuj je . Jest to szczególnie ważne, gdy interfejs jest publiczny, ale jest to bardzo dobry pomysł również w przypadku prywatnych interfejsów.
Wyjątki powinny być obsługiwane tylko w punkcie, w którym kod może zrobić z nimi coś sensownego. Najgorszą opcją obsługi jest nic nie robić na ich temat, co należy zrobić tylko wtedy, gdy jest to dokładnie właściwa opcja. (Kiedy mam taką sytuację w swoim kodzie, dołączam komentarz do tego efektu, aby nie martwić się o puste ciało).
Drugą najgorszą opcją jest zgłoszenie niepowiązanego wyjątku bez dołączenia oryginału jako przyczyny. Problem polega na tym, że informacje zawarte w oryginalnym wyjątku, które umożliwiłyby zdiagnozowanie problemu, zostały utracone; tworzysz coś, z czym nikt nie może nic zrobić (poza narzekaniem, że „to nie działa” i wszyscy wiemy, jak nienawidzimy tych zgłoszeń błędów).
Znacznie lepiej jest rejestrować wyjątek. To pozwala komuś dowiedzieć się, na czym polega problem i go naprawić, ale należy rejestrować wyjątek tylko w punkcie, w którym zostałby utracony lub zgłoszony przez połączenie zewnętrzne. Nie dzieje się tak dlatego, że częstsze rejestrowanie jest poważnym problemem jako takim, ale dlatego, że nadmierne rejestrowanie oznacza, że dziennik zajmuje więcej miejsca i nie zawiera więcej informacji. Po zarejestrowaniu wyjątku możesz z czystym sumieniem zgłosić klientowi / klientowi précis (o ile podasz również czas wygenerowania - lub inny identyfikator korelacji) w tym raporcie, aby można było dopasować krótką wersję w razie potrzeby ze szczegółami).
Najlepszą opcją jest oczywiście całkowite obsłużenie wyjątku, zajmując się sytuacją błędu w całości. Jeśli możesz to zrobić, zrób to! Może to nawet oznaczać, że można uniknąć konieczności rejestrowania wyjątku.
Jednym ze sposobów obsługi wyjątku jest zgłoszenie innego wyjątku, który zapewnia opis problemu na wyższym poziomie (np. „ failed to initialize
” Zamiast „ index out of bounds
”). Jest to dobry wzorzec, o ile nie stracisz informacji o przyczynie wyjątku; użyj szczegółowego wyjątku, aby zainicjować wyjątek cause
wyższego poziomu lub zapisz szczegóły (jak omówiono powyżej). Rejestrowanie jest najbardziej odpowiednie, gdy masz zamiar przekroczyć granicę międzyprocesową, na przykład wywołanie IPC, ponieważ nie ma gwarancji, że klasa wyjątków niskiego poziomu będzie w ogóle obecna na drugim końcu połączenia. Zachowanie się jako dołączonej przyczyny jest najbardziej odpowiednie podczas przekraczania wewnętrznej granicy.
Kolejny wzorzec, który widzisz, to catch-and-release:
try {
// ...
} catch (FooException e) {
throw e;
}
Jest to anty-wzorzec, chyba że masz ograniczenia typu z innych catch
klauzul, co oznacza, że nie możesz po prostu pozwolić, by wyjątek przeszedł sam. To po prostu brzydka funkcja Java.
Nie ma prawdziwej różnicy między sprawdzonymi wyjątkami a niesprawdzonymi, oprócz faktu, że musisz zadeklarować sprawdzone wyjątki, które przekraczają granice metod. Nadal dobrym pomysłem jest dokumentowanie niesprawdzonych wyjątków (z @throws
komentarzem javadoc), jeśli wiesz, że są one celowo wyrzucane przez Twój kod. Nie celowo wrzucaj java.lang.Error
ani jego podklas (chyba że piszesz implementację JVM).
Opinia: Nieoczekiwany przypadek błędu zawsze oznacza błąd w kodzie. Sprawdzone wyjątki są sposobem na zarządzanie tym zagrożeniem, a tam gdzie programiści celowo wykorzystują niesprawdzone wyjątki jako sposób na uniknięcie kłopotów z obsługą przypadków błędów, narastają spory dług techniczny, który będziesz musiał oczyścić przez pewien czas jeśli chcesz solidny kod. Obsługa niechlujnych błędów jest nieprofesjonalna (a spojrzenie na obsługę błędów jest dobrym sposobem na określenie, jak dobry jest naprawdę programista).