2012-10-16 15 views
7

Mam kilka pytań dotyczących obsługi wyjątków w Javie. Czytałem trochę o tym i otrzymałem sprzeczne wytyczne.Dobre praktyki dotyczące obsługi wyjątków Java

Best Practices for Exception Handling

Chodźmy dzięki wspomnianym artykule:

Stwierdza, że ​​należy generalnie unikać sprawdzonych wyjątków jeśli „Kod Klient nie może nic zrobić”. Ale co to dokładnie oznacza? Czy wyświetlenie komunikatu o błędzie w GUI jest wystarczającym powodem, aby bulgotać sprawdzony wyjątek? Ale zmusiłoby to programistę GUI do pamiętania, aby uchwycić RuntimeExceptions i ich potomków, aby wyświetlić potencjalne informacje o błędzie.

Drugi widok przedstawiony w tym artykule jest taki, że należy unikać wynalezienia własnych klas wyjątków, chyba że chcę zaimplementować w nich pewne pola/metody celne. Generalnie nie zgadzam się z tym, moja dzisiejsza praktyka była wręcz przeciwna: zawijałem wyjątki w mojej własnej strukturze wyjątków, aby odruchowe cele były realizowane przez klasy, które piszę, nawet jeśli tylko rozszerzają wyjątek bez dodawania nowych metod. Myślę, że pomaga to w bardziej elastycznym posługiwaniu się nimi w wyższych warstwach, a generalnie jest bardziej zrozumiały i czytelny dla programisty, który użyje tych klas.

Zaimplementowałem kod dzisiaj "nowy sposób" przedstawiony w artykule rzucając RuntimeException tu i tam, a następnie pozwól Sonar go przeanalizować. Aby wprowadzić zamieszanie jeszcze bardziej, Sonar oznaczył moje Wyrażenia RuntimeException jako błędy główne z komunikatem takim jak "Unikaj wyrzucania wyjątków typu root, wrap'em we własnych typach".

Wygląda to dość kontrowersyjnie, jak myślisz?

Też słyszałem od jednego z tech-leadów dzisiaj, że właśnie opakowywanie wyjątków jest złe, "ponieważ to jest naprawdę kosztowna operacja dla JVM". Dla mnie, po drugiej stronie, rzucanie SQLExceptions lub IOExceptions wszędzie wygląda jak odrobina przełamywania enkapsulacji ..

Jaki jest twój ogólny stosunek do pytań, które tutaj przedstawiłem?

  1. Kiedy zawinąć wyjątków w moich własnych typów, kiedy nie powinien to zrobić?

  2. Gdzie jest ten punkt „klient nic o tym nie może zrobić, wyrzucić wyjątek środowiska wykonawczego? '

  3. Co z problemami z wydajnością?

+0

Niestety nie jest to konstruktywne dla SO, jak na najczęściej zadawane pytania. Możesz spróbować wypróbować programmers.stackexchange.com - co jest powiedziane, kupić "Efektywną Javę" Joshua Blocha. Każdy, kto poważnie myśli o Javie, powinien posiadać kopię. –

+0

Zdecydowanie migrowałbym to do Programmers.SE, gdybym mógł. Czy był czas, kiedy mogliśmy to zrobić? A może po prostu zawsze nie mogłem się doczekać tego czasu? –

+0

https://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html to dobra lista dobrych praktyk. – bla

Odpowiedz

2

To wygląda jak tech-ołów, jak często, uciekł jego roli dewelopera, ponieważ nie był dobry.

Moje porady byłoby:

  • wolą wyjątków czasu wykonywania przez sprawdzonych wyjątków, zwłaszcza jeśli nie jesteś jedynym klientem swojej API. Użycie sprawdzonego wyjątku zmusza każdego klienta do obsługi wyjątku, nawet jeśli nie może nic z tym zrobić. Jeśli tak naprawdę chcesz robić (tzn.zmuszając rozmówcę do obsłużenia go), wtedy sprawdzany wyjątek jest tym, czego potrzebujesz.
  • Jeśli jedyną rzeczą, którą klient może zrobić po wystąpieniu wyjątku, jest wyświetlenie bardziej lub mniej ogólnego komunikatu o błędzie, na przykład "Ups, coś złego się stało, spróbuj ponownie lub powróć do strony powitalnej", a następnie zdecydowanie użyj wyjątków czasu wykonywania. Większość frameworków prezentacji udostępnia sposób korzystania z ogólnej procedury obsługi błędów.
  • zdecydowanie używaj wyjątków powiązanych z warstwą abstrakcji. Wyrzucanie wyjątku SQLException z usługi wysokiego poziomu nie jest wystarczające. Używaj istniejących typów wyjątków, gdy są one odpowiednie (np. IllegalArgumentException do sygnalizowania nielegalnego argumentu). W przeciwnym razie zawiń wyjątek niskiego poziomu do wyższego poziomu, odpowiedniego typu wyjątku. Kosztowne jest wyrzucenie wyjątku. To, czy owija się w inną, czy nie, nie ma większego znaczenia. I tak powinno się to zdarzyć wyjątkowo.
+0

Ale o ile rozumiem, owijanie wymaga ponownego rzucenia przekazywanie "starego" wyjątku jako parametru konstruktora do "nowego" wyjątku. Czy koszt złapania i wyrzucenia nie wynosi 200% początkowych kosztów? –

+3

Wyrzucanie wyjątków jest droższe niż "jeśli", ale nie jest to taki świder wydajnościowy. Bez znaczenia w porównaniu z jakimkolwiek połączeniem między procesami lub operacją IO. Najpierw zrób to dobrze, a następnie zoptymalizuj tylko w razie potrzeby, a jeśli zmierzyłeś, że jest to przyczyną problemu z wydajnością. Nie będzie. –

+0

200% z kilku instrukcji to nadal kilka instrukcji. –