Więc pomyślałem, że dobrze rozumiem podstawową obsługę wyjątków w Javie, ale ostatnio czytałem kod, który wprowadził mnie w zakłopotanie i wątpliwości. Moją główną wątpliwością, którą chcę się tutaj zająć, jest to, kiedy osoba powinna użyć deklaracji metody Javy, jak poniżej:
public void method() throws SomeException
{
// method body here
}
Z czytania kilku podobnych postów wynika, że rzucania są używane jako rodzaj deklaracji, że SomeException może zostać wyrzucony podczas wykonywania metody.
Moje zamieszanie pochodzi z kodu, który wyglądał tak:
public void method() throws IOException
{
try
{
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
Czy jest jakiś powód, dla którego chciałbyś użyć rzutów w tym przykładzie? Wygląda na to, że jeśli robisz tylko podstawową obsługę wyjątków dla czegoś takiego jak IOException, po prostu potrzebujesz bloku try / catch i to wszystko.
źródło
throws
słowa kluczowego.Musisz tylko dołączyć klauzulę throws do metody, jeśli metoda zgłasza sprawdzony wyjątek. Jeśli metoda zgłasza wyjątek czasu wykonywania, nie ma takiej potrzeby.
Zobacz tutaj, aby zapoznać się z kontekstem wyjątków zaznaczonych i niezaznaczonych: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html
Jeśli metoda wychwytuje wyjątek i zajmuje się nim wewnętrznie (jak w drugim przykładzie), nie ma potrzeby dołączania klauzuli throws.
źródło
Kod, który oglądałeś, nie jest idealny. Powinieneś albo:
Złap wyjątek i obsłuż go; w takim przypadku
throws
jest to niepotrzebne.Usuń
try/catch
; w takim przypadku wyjątek będzie obsługiwany przez metodę wywołującą.Złap wyjątek, prawdopodobnie wykonaj jakąś akcję, a następnie wyślij ponownie wyjątek (nie tylko wiadomość)
źródło
Masz rację, w tym przykładzie
throws
jest to zbędne. Możliwe, że został tam z jakiejś wcześniejszej implementacji - być może wyjątek został pierwotnie wyrzucony, a nie złapany w bloku catch.źródło
Wysłany kod jest nieprawidłowy. Powinien zgłosić wyjątek, jeśli przechwytuje określony wyjątek w celu obsługi IOException, ale zgłasza nie przechwycone wyjątki.
Coś jak:
public void method() throws Exception{ try{ BufferedReader br = new BufferedReader(new FileReader("file.txt")); }catch(IOException e){ System.out.println(e.getMessage()); } }
lub
public void method(){ try{ BufferedReader br = new BufferedReader(new FileReader("file.txt")); }catch(IOException e){ System.out.println("Catching IOException"); System.out.println(e.getMessage()); }catch(Exception e){ System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc."); System.out.println(e.getMessage()); }
}
źródło
W podanym przykładzie metoda nigdy nie zgłosi wyjątku IOException, dlatego deklaracja jest nieprawidłowa (ale poprawna). Domyślam się, że oryginalna metoda wyrzuciła IOException, ale została następnie zaktualizowana, aby obsłużyć wyjątek w ramach, ale deklaracja nie została zmieniona.
źródło
To nie jest odpowiedź, ale komentarz, ale nie mogłem napisać komentarza ze sformatowanym kodem, więc oto komentarz.
Powiedzmy, że jest
public static void main(String[] args) { try { // do nothing or throw a RuntimeException throw new RuntimeException("test"); } catch (Exception e) { System.out.println(e.getMessage()); throw e; } }
Wynik jest
test Exception in thread "main" java.lang.RuntimeException: test at MyClass.main(MyClass.java:10)
Ta metoda nie deklaruje żadnych wyjątków „rzuca”, ale je odrzuca! Sztuczka polega na tym, że zgłaszane wyjątki to RuntimeExceptions (niezaznaczone), które nie muszą być deklarowane w metodzie. Dla czytelnika metody jest to trochę mylące, ponieważ wszystko, co widzi, to „rzut”; instrukcja, ale bez deklaracji wyjątku zgłasza
Teraz, jeśli mamy
public static void main(String[] args) throws Exception { try { throw new Exception("test"); } catch (Exception e) { System.out.println(e.getMessage()); throw e; } }
MUSIMY zadeklarować wyjątki „rzuca” w metodzie, w przeciwnym razie otrzymamy błąd kompilatora.
źródło
throws
jest to wymagane.