Przykład:
foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
Ponieważ kodowanie jest zakodowane na stałe i poprawne, konstruktor nigdy nie zgłosi wyjątku UnsupportedEncodingException zadeklarowanego w specyfikacji (chyba że implementacja Java jest zepsuta, w którym to przypadku i tak się zgubiłem). W każdym razie Java zmusza mnie do zajęcia się tym wyjątkiem.
Obecnie tak to wygląda
try {
foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
}
catch(UnsupportedEncodingException e) { /* won't ever happen */ }
Wszelkie pomysły, jak to zrobić lepiej?
java
exception-handling
użytkownik 281377
źródło
źródło
Odpowiedzi:
Moim nawykiem jest, aby być po bezpiecznej stronie, wkładać
assert
blokadę. Ktoś możetry
później zmienić zawartość bloku, a ty chcesz wiedzieć, czy kod się nie powiedzie, prawda?źródło
assert false;
nie dodaje bałaganu i wyjaśnia, że zakładam, że blok catch nigdy nie zostanie wprowadzony.assert false : "should never happen"
.assert
oznacza, że asercje są włączone. RzucamUnexpectedException
(co ma tę zaletę, że pozwala mi mieć ślad stosu ...).Gdybym dostał cent za każdym razem, gdy widziałem log / błąd „To nigdy nie powinno się zdarzyć”, miałbym ... cóż, dwa centy. Ale nadal ...
Puste bloki catch powodują, że moje pająki odczuwają mrowienie, a większość dobrych narzędzi do analizowania kodu narzeka. Za wszelką cenę unikałbym pozostawienia ich pustych. Jasne, teraz wiesz, że błąd nigdy nie może się zdarzyć, ale za rok ktoś przeprowadzi globalne wyszukiwanie w celu zastąpienia „ISO-8859-1” i nagle może być bardzo trudno znaleźć błąd.
assert false
Propozycja jest dobra, ale ponieważ twierdzenia mogą być wyłączone w czasie wykonywania, są bez gwarancji. UżyłbymRuntimeException
zamiast tego. Nie trzeba ich wychwytywać podczas wywoływania klas, a jeśli kiedykolwiek wystąpią, będziesz mieć ślad stosu, aby podać pełne informacje.źródło
Zawsze tak robiłem:
Może to być trochę gadatliwe (Java to ...), ale przynajmniej dostaniesz błąd asercji, gdy stanie się niemożliwe.
Jeśli implementacja Java jest zepsuta, będziesz chciał otrzymać tak dobry komunikat o błędzie, jak to możliwe, tak szybko, jak to możliwe, zamiast po prostu ignorować niemożliwe. A nawet jeśli realizacja Java nie jest uszkodzony, ktoś mógłby zmienić swój kod do
"UTF8"
(oops - powinno być"UTF-8"
?).W pierwszej kolejności powinien to być wyjątek czasu wykonywania. JDK jest pełen tego rodzaju złych wyborów.
źródło
foobar = new InputStreamReader(p.getInputStream(), Charset.ISO_8859_1);
- czy nie byłoby to ładniejsze i uniknęło kiedyś błędu na zawsze?Jeśli jesteś jedynym programistą, który kiedykolwiek zobaczy ten kod, powiedziałbym, że jest w porządku, ale jeśli nie, to potraktowałbym go jako realną możliwość lub przynajmniej zmienię komentarz „nigdy się nie wydarzy” na coś bardziej przydatnego.
źródło
Część tych wyjątków, która najbardziej mnie denerwuje, to to, że szkodzi mojemu pokryciu kodu.
Kiedy kompulsywnie podchodzę do zasięgu, zwrócę próbę / złapanie, że „nigdy nie może się zdarzyć” (... lub tylko jeśli używam zmutowanej maszyny JVM, która w jakiś sposób zapomniała dołączyć „US-ASCII”) do klasa i metoda, która hermetyzuje to try / catch, i zastępuje zaznaczony wyjątek na jeden ze sposobów wymienionych tutaj (zwykle zgłaszając niesprawdzony wyjątek komunikatem snide).
Następnie moje pokrycie kodu ma trafienie w klasie użyteczności, ale nie we wszystkich odniesieniach do tej operacji rozrzuconych wokół mojego kodu.
Czasami poświęcę trochę czasu na zwinięcie jak operacje w klasie, która ma spójną semantykę. Ale ponieważ jest to dość oczywiste dla moich kolegów z zespołu, co się dzieje, zwykle po prostu staram się, aby było to tak proste, jak tylko mogę i nie martwię się tak bardzo o najlepszy możliwy projekt.
Jednak, jak wspomniano w komentarzu, Guava i inne biblioteki mają sposoby na złagodzenie tego bólu - ale to w zasadzie ta sama strategia. Przenieś irytację poza scenę, aby Twój główny kod nie obejmował zasięgu.
źródło