2013-05-24 17 views
25

W języku Java jest możliwe, aby metoda, która ma nie być zaznaczone oświadczenie throws.Czy można zignorować wyjątek?

Na przykład:

public class TestClass { 
    public static void throwAnException() throws Exception { 
     throw new Exception(); 
    } 
    public static void makeNullPointer() { 
     Object o = null; 
     o.equals(0);//NullPointerException 
    } 
    public static void exceptionTest() { 
     makeNullPointer(); //The compiler allows me not to check this 
     throwAnException(); //I'm forced to handle the exception, but I don't want to 
    } 
} 

Odpowiedz

52

Można spróbować zrobić nic o nim:

public static void exceptionTest() { 
    makeNullPointer(); //The compiler allows me not to check this 
    try { 
     throwAnException(); //I'm forced to handle the exception, but I don't want to 
    } catch (Exception e) { /* do nothing */ } 
} 

pamiętać, w prawdziwym życiu to ekstremalnie nierozważne. To może ukryć błąd i sprawić, byś szukał psów przez cały tydzień, podczas gdy problem był naprawdę kotem (ch). (Chodź, umieścić przynajmniej System.err.println() tam. - Rejestrowanie jest najlepsza praktyka tutaj, jak sugeruje @BaileyS)

Unchecked exceptions in Java rozszerzyć klasę RuntimeException. ich wyrzucanie nie będzie żądać od swoich klientów catch:

// notice there's no "throws RuntimeException" at the signature of this method 
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ { 
    throw new RuntimeException(); 
} 

klas, które rozszerzają RuntimeException nie będzie wymagać deklaracji throws również.

I a word from Oracle o tym:

Oto wiersz wskazówka: Jeśli można zasadnie oczekiwać klient, aby odzyskać od wyjątek, sprawiają, że zaznaczone jest wyjątkiem. Jeśli klient nie może nic zrobić, aby odzyskać od wyjątku, uczynić go niezaznaczonym wyjątkiem.

+6

Bardzo ładny post. Inną rzeczą, którą chciałbym zasugerować, jest przynajmniej nagrywanie zignorowanego wyjątku w rejestratorze. –

+2

Chciałem zgodzić się z tym za okropną kalambur, ale nie mogłem zrobić tego samemu. +1 za dobrą odpowiedź – Craig

+11

@Craig Och, daj spokój, kalambur wnosi post na zupełnie nowy poziom: P – acdcjunior

2

Nie, to podnosi błąd kompilatora. Będąc sprawdzonym wyjątkiem, musisz go przechwycić lub rozpropagować, deklarując, że twoja metoda potencjalnie je rzuca. Sprawdź this i this.

+0

nie jestem wyborca ​​w dół, ale twoja odpowiedź jest nieco niekompletna, rozważ @tarrsalah, możesz znaleźć odpowiedź –

+3

Nie jest ona również w dolnej części, ale zaleca się również podsumować ważne punkty w odnośnikach powiązanych, tak, że odpowiedź może stać sama, nawet jeśli powiązane dokumenty są przeniósł się lub zniknął. –

+0

Zauważono, chłopaki. Dzięki. – LexLythius

1

Wiem, w przypadku jest to niemożliwe. Tylko niezaznaczony wyjątek, kompilator może pominąć, aby sprawdzić. takie jak RuntimeException.

+0

Ta odpowiedź jest wewnętrznie sprzeczna. Najpierw mówisz, że to niemożliwe, a potem wyjaśniasz (rodzaj), jak to jest możliwe. Który to będzie? –

+0

Właśnie zaktualizowałem swoją odpowiedź, jest to niemożliwe w przypadku (przypadek użytkownika). A następnie wyjaśnij, czy użytkownik naprawdę chce rzucić wyjątek, który nie może zostać przechwycony, możemy użyć tylko niezaznaczonego wyjątku. – Stony

3

W Javie istnieją dwa rodzaje Exceptions, zaznaczone wyjątki i niezaznaczone wyjątki.

  • Exception to sprawdzony wyjątek, który musi zostać przechwycony lub zgłoszony.
  • NullPointerException jest RuntimeException (kompilator nie zmusza ich do zgłoszenia w rzuty Claus) można go ignorować, ale nadal mogą występować w Runtime, a aplikacja będzie katastrofy.

Od Exception dokumentacji:

klasy wyjątek i wszelkich podklasy, które nie są również podklasy RuntimeException są sprawdzane wyjątki. Sprawdzane wyjątki muszą być zadeklarowane jako w klauzuli throws metody lub konstruktora, jeśli mogą być wygenerowane przez wykonanie metody lub konstruktora i propagować poza granicę metody lub konstruktora.

Z dokumentacji RuntimeException:

RuntimeException jest nadklasą tych wyjątków, które mogą być rzucony podczas normalnej pracy Java Virtual Machine.

Wyjątek RuntimeException i jego podklasy są niezaznaczonymi wyjątkami. Niezaznaczone wyjątki nie muszą być zadeklarowane w metodzie lub klauzuli rzutów konstruktora, jeśli można je rzucić wykonaniem metody lub konstruktora i propagować poza granicę konstruktora metody lub .

+1

Oczywiście, jeśli zignorujesz 'wyjątek NullPointerException' (lub jakikolwiek wyjątek) (w przeciwieństwie do przechwytywania i odrzucania), aplikacja ulegnie awarii. –

3

Istnieją 3 rzeczy, które możesz zrobić:

  • rzucać RuntimeException (lub coś rozciągający się RuntimeException, jak NullPointerException, IllegalArgumentException, ...), nie trzeba złapać je, ponieważ są one niezaznaczone wyjątki.

  • połowu wyjątek i nic nie robić (nie zalecane):

    public static void exceptionTest() { 
        makeNullPointer(); //The compiler allows me not to check this 
        try { 
         throwAnException(); //I'm forced to handle the exception, but I don't want to 
        } catch (Exception e) { 
         // Do nothing 
        } 
    } 
    
  • Zmień exceptionTest() deklaracja powiedzieć, że zgłasza Exception i niech metodę nazywając go złapać Exception i robić to, co jest właściwe:

    public static void exceptionTest() throws Exception { 
        makeNullPointer(); //The compiler allows me not to check this 
        throwAnException(); //I'm no more forced to handle the exception 
    } 
    
+0

Sugerowałbym, że jeśli metoda jest zadeklarowana jako wyrzucanie sprawdzanego wyjątku, ale oczekuje się, że konkretne wywołanie nigdy nie zostanie wyrzucone, należy przechwycić sprawdzony wyjątek i zawinąć go w coś takiego jak "RuntimeException". Rzeczywiście, uznałbym takie zachowanie za właściwe, nawet jeśli (być może * zwłaszcza, jeśli *) metoda wywołująca wywołanie powinna wyrzucić ten wyjątek w różnych okolicznościach. Jeśli 'LoadDocument (nazwa pliku)' wyrzuca 'FileNotFoundException', powinno to wskazywać, że' filename' nie został znaleziony - nie, że jakiś inny niezbędny plik, taki jak szablon, nie był dostępny. – supercat

1

innych odpowiedzi rację w tym, że właściwie powiedzieć, czego powinno być zrobić, ale to jest możliwe, aby rzucić niezadeklarowany sprawdzony wyjątek. Można to zrobić na kilka sposobów; najprostszą jest:

public void methodThatSecretlyThrowsAnException() { 
    Thread.currentThread().stop(new Exception()); 
} 

lub jeśli twoim celem jest, aby zawinąć istniejący sposób, który nie deklarują jej wyjątek

public void methodThatSecretlyThrowsAnException() { 
    try { 
     methodThatAdmitsItThrowsAnException(); 
    } catch(final Exception e) { 
     Thread.currentThread().stop(e); 
    } 
} 

(trzeba dodawać, że nigdy nie powinno się tego robić.)

1

Wystarczy wychwycić wyjątek i nic z nim nie zrobić, pozostawić tak, jak jest, i wychwycić ogólny wyjątek, jeśli nie wiesz o konkretnym wyjątku:

try{ 
//Your logic goes here 
} 
catch(Exception e)//Exception is generic 
{ 
//do nothing 
} 
0

Nie jest wskazane unikanie wyjątku z pustym blokiem catch, nawet jeśli masz całkowitą pewność, że w żadnym wypadku nie zawiedzie. Czasami nie jesteśmy świadomi czynnika ludzkiego.

Jeśli masz pewność, że wyjątek jest mało prawdopodobny (jeśli nie jest niemożliwy), powinieneś utworzyć własny wyjątek i zawinąć w nim nieoczekiwany wyjątek.

Na przykład:

private class UnlikelyException extends RuntimeException { 
    public UnlikelyException (Exception e){ 
     super (e); 
    } 
} 

następnie owinąć kod z bloku try-catch i rzucać wyjątek, którego nie trzeba złapać

try { 
    // Your code 
} catch (Exception e) { 
    throw new UnlikelyException(e); 
} 
Powiązane problemy