2013-05-10 20 views
6

Von Java 7, können wir die Try-with-Ressourcen-Anweisung:Wie kann die unterdrückte Ausnahme im "try" -Block abgerufen werden?

static String readFirstLineFromFile(String path) throws IOException { 
    try (BufferedReader br = 
        new BufferedReader(new FileReader(path))) { 
     return br.readLine(); 
    } 
} 

wenn br.readLine() und br.close()beiden Würfe Ausnahmen, readFirstLineFromFile wird Wurf die Ausnahme von dem try-Block (Ausnahme: von br.readLine()), und die Ausnahme von implizit schließlich Block der Try-with-Ressourcen-Anweisung (die Ausnahme von br.close()) wird unterdrückt werden.

In diesem Fall können wir abrufen unterdrückt Ausnahmen von der impliziten schließlich blockieren, indem die getSuppresed Methode von Ausnahme des try-Block wie dieser Aufruf:

try { 
    readFirstLineFromFile("Some path here..."); // this is the method using try-with-resources statement 
} catch (IOException e) {  // this is the exception from the try block 
    Throwable[] suppressed = e.getSuppressed(); 
    for (Throwable t : suppressed) { 
     // Check t's type and decide on action to be taken 
    } 
} 

Aber Angenommen, wir müssen mit einer Methode arbeiten, die mit einer älteren Version als Java 7 geschrieben wurde, in der der finally-Block verwendet wird:

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { 
    BufferedReader br = new BufferedReader(new FileReader(path)); 
    try { 
     return br.readLine(); 
    } finally { 
     if (br != null) br.close(); 
    } 
} 

dann, wenn br.readLine() und br.close() noch einmal beide Ausnahmen werfen, wird die Situation umgekehrt werden. Das Verfahren readFirstLineFromFileWithFinallyBlock wird throw die Ausnahme von den schließlich (die Ausnahme von br.close()) blockieren, und die Ausnahme von dem try-Block (ausgenommen br.readLine()) werden unterdrückt.

Also meine Frage ist: Wie können wir die unterdrückt Ausnahmen vom try-Block im zweiten Fall abrufen ?

Quelle: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Antwort

6

Sie können nicht, im Grunde. Die unterdrückte Ausnahme ist verloren, wenn br.close() wirft.

Die nächstgelegene Sie wäre kommen könnte einen catch Block zu haben, die den Wert in eine locla Variable zuweist:

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { 
    IOException exception = null; 
    BufferedReader br = new BufferedReader(new FileReader(path)); 
    try { 
     return br.readLine(); 
    } catch (IOException e) { 
     exception = e; 
    } finally { 
     try { 
     if (br != null) br.close(); 
     } catch (IOException e) { 
     // Both the original call and close failed. Eek! 
     // Decide what you want to do here... 
     } 
     // close succeeded, but we already had an exception 
     if (exception != null) { 
     throw exception; 
     } 
    } 
} 

... aber das nur Griffe IOException (eher als alle ungeprüften Ausnahmen) und ist schrecklich chaotisch.

+0

Ich werde "JonSkeet" zu den folgenden TAGS hinzufügen ... ^^ –

1

die Ausnahme von dem try-Block (ausgenommen br.readLine()) wird unterdrückt.

Das ist nicht ganz richtig.Die Java Language Specification writes:

  • Wenn die Ausführung des try-Block wegen eines Wurfes eines Wertes V abrupt beendet hat, dann gibt es eine Wahl:

    • Wenn die Laufzeit Der Typ von V ist nicht mit einer abfangbaren Ausnahmeklasse einer catch-Klausel der try-Anweisung kompatibel, dann wird der finally-Block ausgeführt. Dann gibt es eine Auswahl:

      • Wenn der finally-Block normal abgeschlossen ist, dann wird die try-Anweisung beendet abrupt wegen eines Einwurfs des Wertes V.

      • Wenn der finally-Block abrupt Grund S abgeschlossen ist, dann wird die try-Anweisung aus Gründen S abrupt beendet (und das Werfen von Wert V wird verworfen und vergessen).

Das heißt, wird die Ausnahme "verworfen und vergessen", nicht nur unterdrückt.

BTW, wie die mechanism für das Anfügen einer unterdrückten Ausnahme an eine andere Ausnahme in Java 7 eingeführt wurde, gab es in Java 6 keine allgemeine Unterstützung. Daher kann Code Targeting Java 6 davon nicht Gebrauch machen Feature.

Verwandte Themen