2012-07-02 15 views
16

Czasami skończę konieczności złapać wyjątek, że wiem, nigdy nie może się zdarzyć, tak jak tutajJak radzisz sobie z wyjątkami "niemożliwymi" w Javie?

URLDecoder.decode("some string", "UTF-8"); //No unknown encoding possible 

lub tutaj:

public void methodWithURL(URL url){ 
    URI uri = new URI(url); //No invalud URI syntax possible 
} 

Jak to obsługiwać? Generalnie rejestruję zabawny błąd dotyczący zmiany praw wszechświata, a następnie wyrzucam RuntimeException. Czy istnieje lepszy sposób?

+3

try/catch (XXXException _ex) {throw new AssertionError (_ex);} – bestsss

+0

@bestsss Też słyszałem o AssertionError jako alternatywa dla RuntimeException. Czy jest to ogólny sposób, aby zrobić to przez RuntimeException lub po prostu lepszy sposób podklasy tego rodzaju błędów? dzięki! (również, możesz chcieć pisać w sekcji odpowiedzi) – Miquel

+1

Błąd nie rozszerza wyjątku, więc pomija nadużywane 'try/catch (Exception any)'. Wszystko, co przechwytuje 'Throwable', powinno jawnie zawierać w /' Błąd'. Kod klienta nie może również uchwycić "błędu" bez przyczyny. Wyłącznie rejestrowanie wyjątku, który * nie może się zdarzyć * zazwyczaj nie jest właściwą rzeczą. I nie, nie chcę wypróbowywać odpowiedzi :) – bestsss

Odpowiedz

9

Łapię Exception i zawijam w Error. z DOC Error:

Błąd jest podklasą Throwable, który wskazuje, że poważne problemy rozsądny wniosek nie powinien starać się złapać.

+0

Wielkie dzięki Julien. Jestem teraz raczej przekonany, że najlepszym sposobem jest wyrzucenie pochodnej "Błąd". @ Bestsss również kilka sugestii w sekcji komentarza pytania, w tym użycie AssertionError – Miquel

+0

+1 Teraz _ to jest naprawdę solidna odpowiedź. Nie jest on specyficzny jak 'AssertionError' (który może wyglądać dziwnie w przypadku braku instrukcji" assert ") i ma taki sam efekt jak' RuntimeException'. Plus oznacza problem z "systemem", a nie z logiką kodu. Lubić. Zastanawiam się, czy to podejście jest powszechnie znane, czy też są jakieś wady? –

+1

* Plus oznacza problem z "systemem" * To jest "InternalError" dla. Używałem go w wersji 1.1, ale zmieniono na "AssetionError" w wersji 1.4 (oferuje również c-tor w/Throwable). Również niektóre błędy mogą nie być dokładnie spowodowane błędem systemu, ale programowaniem tych lub baz danych. Przy okazji, kilka miejsc w java używa 'System.exit (-1)' – bestsss

3

Cóż, IMHO tam jest lepszy sposób niż "log [ging] zabawny błąd, w jaki sposób zmieniły się prawa wszechświata", ponieważ robiąc to jesteś "bycie słodkim", co wśród przyjaciół jest w porządku, ale nie jest powszechnie przyjęty (gra słów nie jest przeznaczona). Twój kod może zostać odczytany przez innych i jeśli twój humor spadnie (na nich), nie zrobiłeś żadnych przyjaciół.

Wiele przewodników po stylach zawiera sugestie dotyczące niemożliwych wyjątków. Można użyć pustego bloku catch z parametrem wyjątku o nazwie willNeverHappen; możesz umieścić komentarz w pustym bloku; można rzucić wyjątek czasu wykonywania (prawdopodobnie najlepszy, ponieważ MIGHT wpisana błędnie UTF-8!)

Jeśli chcesz być super ambitny, można napisać adnotacji, jak SneakyThrows in Lombok. To, czy uważasz to za "lepsze", to po prostu kwestia gustu. :)

Pamiętaj, że to pytanie zostało omówione na https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-cannot-ever-be-thrown.

+0

Dzięki za odpowiedź Ray; Nie jestem pewien, czy poleciłbym puste bloki blokujące (komentarz lub nie), ale masz punkt, że niemożliwe opcje * mogą * stać się możliwe jeden dzień. Co do humoru, jestem pewien, że istnieje wiele opinii (być może zależy to od kultury firmy?), Ale masz rację, że nikt nie powinien cierpieć z powodu błędu przez wiele godzin, tylko dlatego, że znalazł się w wyniku niewłaściwego wyjątku i zabawnej wiadomości. – Miquel

+0

Nienawidzę również pustego bloku catch: wyjątki "jedzenia" to okropna praktyka. I tak, próbowałem powiedzieć, że humor był w porządku w niektórych kręgach; niesie ze sobą ryzyko, że nie zrozumie tego przyszły czytelnik kodu, więc takie podejście powinno być starannie przemyślane. Jeśli wybierzesz, najlepiej uczynić go czymś, co czytelnicy zrozumieją, a nie czymś, co opiera się na popkulturze lub odniesieniem do czegoś ezoterycznego. "Naruszenie praw wszechświata" jest _prawdopodobne_ w porządku. Powiedział, że 'RuntimeException' lub jego kuzyn' Error' są najlepszym wyborem. –

5

Chciałbym pominąć zabawną wiadomość.

BTW: Miałem przypadek, w którym fragment kodu (w małej bibliotece) zakładał, że kodowanie będzie dostępne. Tylko został wdrożony na ograniczonym urządzeniu i eksplodował w czasie wykonywania.

Sprawdzone wyjątki służą do pokazania miejsc w naszym kodzie, w których powinniśmy zatrzymać się na chwilę i zastanowić się, jakie ścieżki są mniej przejechane (jak w "co moja aplikacja robi, gdy sieć umiera" i inne przypadki narożne). Zawijanie ich w IllegalStateException i rethrowing to rodzaj podpisanej umowy, w której programista mówi: "tak, wszystkie ryzyka uważam, że biorę pełną odpowiedzialność za to miejsce właśnie tutaj". Gdyby nie było dla sprawdzonych wyjątków, nie mielibyśmy możliwości poznać świadomej decyzji od zwykłego braku myśli.

+0

Bardzo dziękuję za twój przykład, że niemożliwe stało się możliwe. Właśnie tego się obawiałem i dlatego chciałem sprawdzić z wami. Poza tym nie protestowałem przeciwko sprawdzonym wyjątkom, uważam je za podstawową część Javy, ale zastanawiałem się, jak poradzić sobie z niemożliwymi (naprawdę nieprawdopodobnymi?) – Miquel

0

Oto moje rozwiązanie - opracowany dla Androida, ale może być łatwo dostosowany do „zwykłej” Java:

public class ImpossibleException extends RuntimeException { 
    public ImpossibleException(@NonNull String whyNotPossible) { 
     this(whyNotPossible, null); 
    } 

    public ImpossibleException(@NonNull String whyNotPossible, Throwable throwable) { 
     super("Impossible exception: " + whyNotPossible, throwable); 
     Log.e("Impossible", whyNotPossible, throwable); 
    } 
} 

Zastosowanie:

try { 
    byte[] data = "Hello".getBytes("utf-8"); 
    Log.i("Test", "data.length=" + data.length); 
} catch (UnsupportedEncodingException e) { 
    throw new ImpossibleException("Android always supports utf-8", e); 
} 

Konstruktor whyNotPossible oznacza, że ​​nie ma potrzeby, aby zalogować się błąd gdzie to się dzieje, a także nie ma potrzeby komentowania.

Zgaduję, że to kwestia gustu, jeśli powinno to być ImpossibleException extends RuntimeException lub ImpossibleError extends Error.

Powiązane problemy