2014-09-28 15 views
9

geworfen wird, so habe ich hier ein wenig Code und ich bin mir nicht sicher, ganz wie es in dem Fall reagieren würde, dass die reader.close() -Methode eine Ausnahme auslöst.Wird schließlich vollständig ausgeführt, wenn eine Ausnahme in schließlich Block

public void someMethod(String s) throws IOException{ 
    BufferedReader reader = Files.newBufferedReader(filePath,cs); 
    listRWLock.readLock().lock(); 
    try{ 
    //miscellaneous code involving reading 
    }finally{ 
    reader.close() 
    listRWLock.readLock().unlock() 
    } 
} 

ListRWLock ist ein ReentrantReadWriteLock. Wenn die reader.close() -Methode eine Ausnahme auslöst, würde die Anweisung danach fehlschlagen? Ich habe versucht, nach dem Thema zu suchen, und während ich etwas über die endgültige Ausführung im Falle von Return-Anweisungen bekommen habe, habe ich keine Details darüber gefunden, was passiert, wenn eine Ausnahme in den finally-Block geworfen wird.

Vielen Dank im Voraus.

+1

Die nachfolgenden Aussagen sollten nicht ausgeführt werden. Außerdem kann 'return' in' finally' Block vorherige Ausnahmen überschreiben. –

Antwort

4

Grundsätzlich schließlich Klauseln gibt es richtige Freigabe einer Ressource zu gewährleisten. Wenn jedoch eine Ausnahme in den finally-Block geworfen wird, verschwindet diese Garantie.

Ein Problem, für das es keine wirklich saubere Lösung gibt, ist, dass Code im finally-Block selbst eine Ausnahme auslösen könnte. In diesem Fall würde die Ausnahme im finally-Block von der Ausnahme ausgelöst und nicht von einer Ausnahme innerhalb des try-Blocks. Da Code im finally-Block soll „Bereinigung“ Code sein, könnten wir Ausnahmen zu behandeln dort auftretenden als sekundäre entscheiden, und eine excplicit Fang zu setzen:

public int readNumber(File f) throws IOException, NumberFormatException { 
    BufferedReader br = new BufferedReader(new 
    InputStreamReader(new FileInputStream(f), "ASCII")); 
    try { 
    return Integer.parseInt(br.readLine()); 
    } finally { 
    try { br.close(); } catch (IOException e) { 
     // possibly log e 
    } 
    } 
} 

einige andere Dinge über schließlich Blöcke zu beachten:

  1. das gleiche ‚zwingende‘ Problem, das wir mit Ausnahmen erwähnten tritt auf, wenn ein Wert aus einem finally-Block zurückkehrt: dies würde jeden Rückgabewert außer Kraft setzen, dass der Code im try-Block zu Rückkehr wollte. In der Praxis ist die Rückgabe eines Wertes aus einer finally-Klausel selten und wird nicht empfohlen.
  2. Eigentlich Beenden des Programms (entweder durch System.exit() oder durch verursacht einen schwerwiegenden Fehler aufrufen, die den Vorgang abzubrechen verursacht: manchmal bezeichnet informell als „Hotspot“ oder „Dr. Watson“ in Windows) wird Verhindere, dass dein endgültiger Block ausgeführt wird!
  3. Es gibt nichts, um uns zu stoppen Schachteln versuchen/fangen/endlich blockiert (für Beispiel, einen Versuch/endlich Block in einem Versuch/catch Block oder umgekehrt), und es ist nicht so eine ungewöhnliche Sache zu tun.
+0

Sie haben Ihre Antwort direkt kopiert und gemischt von [hier] (http://www.javamex.com/tutorials/exceptions/exceptions_finally.shtml) und [hier] (http://softwareengineering.stackexchange.com/a/ 188877/114810)? Einen Satz von jedem von ihnen nehmen! Habe den Anstand, ihnen zumindest Kredit zu geben! –

1

Sie diesen Test sollten,

aber wenn Versuch wirft IO Ausnahme, dann Ihre Leser wird nicht schließen.

Vielleicht haben

catch(IOException ex){ 
     reader.close() 
+0

Falsch und beantwortet die Frage nicht. – EJP

1

Eine Ausnahme überall in Ihrem Code passieren kann, einschließlich finally Block, so dass Sie es zu fangen, wie anderswo in Ihrem Code. Überprüfen Sie den folgenden Beitrag einige Ideen über die Möglichkeiten bekommen Sie eine solche Situation bewältigen kann:

throws Exception in finally blocks

+0

Beantwortet die Frage nicht. – EJP

4

Sie können etwas tun:

try{ 
    //miscellaneous code involving reading 
}finally{ 
    handlePossibleException(reader); 
    listRWLock.readLock().unlock() 
} 

handlePossibleException(BufferedReader reader) { 
    try { 
     if (reader != null) { 
      reader.close(); 
     } 
    } catch(Exception e) { 
     log.e("reader.close() Exception: ", e); 
     } 
}