2010-12-08 9 views
73

Also dachte ich, ich hätte ein gutes grundlegendes Verständnis der Ausnahmebehandlung in Java, aber ich habe kürzlich Code gelesen, der mir einige Verwirrung und Zweifel bereitet hat. Mein Haupt Zweifel, dass ich hier ansprechen möchte, ist, wenn sollte eine Person die Verwendung in einer Java-Methode Erklärung wirft wie folgt aus:Wann verwendet man Würfe in einer Java-Methodendeklaration?

public void method() throws SomeException 
    { 
     // method body here 
    } 

Von einige ähnliche Beiträge lesen entnehme ich, dass wirft als eine Art Erklärung verwendet wird, dass SomeException könnte während der Ausführung der Methode ausgelöst werden.

Meine Verwirrung kommt von einem Code, der so aussah:

 public void method() throws IOException 
    { 
      try 
      { 
       BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
      } 
      catch(IOException e) 
      { 
       System.out.println(e.getMessage()); 
      } 
    }

Gibt es einen Grund, dass Sie ein in diesem Beispiel wirft wollen würde benutzen? Es scheint, dass, wenn Sie nur grundlegende Ausnahmebehandlung von etwas wie eine IOException tun, die Sie einfach den try/catch-Block benötigen und das ist es.

Antwort

71

Wenn Sie einen Ausnahmetyp abfangen, müssen Sie ihn nicht werfen, es sei denn, Sie werden ihn erneut auslösen. In dem von Ihnen geposteten Beispiel sollte der Entwickler das eine oder andere getan haben, nicht beide.

Wenn Sie nichts mit der Ausnahme machen, sollten Sie es normalerweise nicht abfangen.

Die gefährlichste Sache, die Sie tun können, ist eine Ausnahme zu fangen und nichts damit zu tun.

Eine gute Diskussion, wenn es entsprechende Ausnahmen zu werfen ist hier

When to throw an exception?

+1

Sollten unkontrollierte Ausnahmen auch in der Methodensignatur mit einem 'throws' deklariert werden, oder ist es üblich, nur 'throws' für geprüfte Ausnahmen zu verwenden? – Cody

2

Sie richtig sind, in diesem Beispiel die throws ist überflüssig. Es ist möglich, dass es dort von einer vorherigen Implementierung übrig geblieben ist - vielleicht wurde die Ausnahme ursprünglich geworfen, anstatt im Catch-Block gefangen zu werden.

1

In dem Beispiel, das Sie angegeben haben, wird die Methode niemals eine IOException auslösen, daher ist die Deklaration falsch (aber gültig). Meine Vermutung ist, dass die ursprüngliche Methode die IOException ausgelöst hat, aber sie wurde dann aktualisiert, um die Ausnahme innerhalb zu behandeln, aber die Deklaration wurde nicht geändert.

18

Sie müssen nur eine throws-Klausel in eine Methode einschließen, wenn die Methode eine geprüfte Ausnahme auslöst. Wenn die Methode eine Laufzeitausnahme auslöst, ist dies nicht erforderlich.

Sehen Sie hier für einige Hintergrundinformationen auf vs ungeprüften Ausnahmen geprüft: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Wenn die Methode die Ausnahme und befasst sich mit ihm fängt innen (wie in Ihrem zweiten Beispiel), dann gibt es keine Notwendigkeit, eine throws-Klausel aufzunehmen.

7

Der Code, den Sie angeschaut haben, ist nicht ideal. Sie sollten entweder:

  1. Fang die Ausnahme und damit umgehen; In diesem Fall ist die throws unnötig.

  2. Entfernen Sie die try/catch; In diesem Fall wird die Exception von einer Aufrufmethode behandelt.

  3. fangen die Ausnahme, möglicherweise eine Aktion durchführen und dann rethrow die Ausnahme (nicht nur die Nachricht)

1

Der Code, den Sie ist falsch geschrieben, sollte es eine Ausnahme auslösen, wenn eine bestimmte Fang Ausnahme, um IOException zu verarbeiten, aber nicht eingefangene Ausnahmen zu werfen.

Etwas wie:

public void method() throws Exception{ 
    try{ 
      BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
    }catch(IOException e){ 
      System.out.println(e.getMessage()); 
    } 
} 

oder

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()); 
    } 

}

0

Dies ist keine Antwort, sondern ein Kommentar, aber ich konnte keinen Kommentar mit einem formatierten Code schreiben, so Hier ist der Kommentar.

Lets sagen, es gibt

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; 
    } 
} 

Der Ausgang ist

test 
Exception in thread "main" java.lang.RuntimeException: test 
    at MyClass.main(MyClass.java:10) 

Diese Methode deklarieren keine "wirft" Ausnahmen, sondern wirft sie! Der Trick besteht darin, dass die ausgelösten Ausnahmen RuntimeExceptions (nicht markiert) sind, die nicht für die Methode deklariert werden müssen. Es ist ein bisschen irreführend für den Leser der Methode, da alles, was sie sieht, ein "Wurf e;" Erklärung, aber keine Erklärung der Würfe Ausnahme

Wenn wir nun

public static void main(String[] args) throws Exception { 
    try { 
    throw new Exception("test"); 
    } catch (Exception e) { 
    System.out.println(e.getMessage()); 
    throw e; 
    } 
} 

haben wir müssen erklären, die „throws“ Ausnahmen in der Methode sonst wir einen Compiler-Fehler erhalten.