2011-01-14 17 views
57

Perché fare questoPerché usare finalmente al posto del codice dopo cattura

} catch (SQLException sqle) { 
    sqle.printStackTrace(); 
} finally { 
    cs.close(); 
    rs.close(); 
} 

Invece di questo

} catch (SQLException sqle) { 
    sqle.printStackTrace(); 
} 
rs.close(); 
cs.close(); 
+0

Nota che hai ancora un problema in quanto se il tuo primo 'close' genera un'eccezione, non arrivi mai al secondo. A quanto pare, è generalmente una buona idea non usare botch 'catch' e' finally' con lo stesso blocco 'try'. –

+1

Non più necessario con java7: AutomaticResourceManagement, provare (new resourceDeclartion()) {} –

risposta

63

Perché se un'eccezione viene buttato viene eseguito alcun codice dopo il blocco trya meno 'colto l'eccezione. Un blocco finally viene sempre eseguito indipendentemente da ciò che accade all'interno del blocco try.

+5

> "a meno che non venga rilevata un'eccezione" - L'escetion viene catturato con catch no? – code511788465541441

+0

Sto parlando dell'architettura generale di try/catch/finally, non del suo esempio specifico. –

+8

Questa risposta è corretta, potrebbe essere lanciato un diverso tipo di eccezione. – pilavdzice

6

perché assicura che la roba nel blocco finally viene eseguito. Stuff after catch potrebbe non essere eseguito, ad esempio, c'è un'altra eccezione nel blocco catch, che è molto possibile. Oppure fai semplicemente ciò che hai fatto e genera un'eccezione che racchiude l'eccezione originale.

1

Il tuo secondo approccio non eseguirà le istruzioni di chiusura perché è già stato lasciato il metodo.

22

Guarda il tuo blocco di cattura - sta per lanciare DAOException. Quindi le dichiarazioni dopo il blocco catch non verranno eseguite anche nell'esempio che hai dato. Quello che hai mostrato (avvolgendo un'eccezione in un'altra) è uno schema comune, ma un'altra possibilità è che il blocco catch "accidentalmente" generi un'eccezione, ad es. perché una delle chiamate che effettua non riesce.

Inoltre, potrebbero esserci altre eccezioni non catch - perché hai dichiarato che il metodo le ha generate o perché sono eccezioni non controllate. Vuoi veramente perdere risorse perché un IllegalArgumentException è stato gettato da qualche parte?

0

Questo è il modo per evitare perdite di risorse

0

Il codice nel blocco finally andranno chiamato prima che l'eccezione viene rilanciati dal blocco catch. Questo assicura che ogni codice di pulizia che hai inserito nel blocco finally venga chiamato. Il codice al di fuori del blocco finally non verrà eseguito.

2

La parola chiave finally garantisce che il codice venga eseguito. Nell'esempio in basso, le dichiarazioni di chiusura NON sono eseguite. Nell'esempio in alto, vengono eseguiti (ciò che si vuole!)

+0

Quindi il codice si interrompe magicamente in esecuzione dopo catch() {}? Io non la penso così – weiglt

8

Perché se viene generata un'eccezione,

  • codice nella clausola finally eseguirà come il l'eccezione si propaga verso l'esterno, anche se l'eccezione interrompe il resto dell'esecuzione del metodo;

  • Il codice dopo il blocco try/catch non viene eseguito a meno che l'eccezione non venga catturata da un blocco catch e non ricalcolata.

+1

+1 per il secondo punto –

0

considerare che la cattura può generare un'eccezione alle funzioni di livello superiore nello stack di chiamate. Questo condurrà alla chiamata finale prima di lanciare l'eccezione al livello superiore.

0

In http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html Questo è fuorviante (e potrebbe aver avuto origine la questione):

The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.

1. The new FileWriter statement fails and throws an IOException. 
2. The list.get(i) statement fails and throws an IndexOutOfBoundsException. 
3. Everything succeeds and the try block exits normally. 

Il quarto modo (un'eccezione diversa IOException e IndexOutOfBoundsException è gettata) manca. Il codice illustrato nella pagina precedente rileva solo (1) e (2) prima di ricorrere a finally.

Sono anche nuovo in Java e ho avuto la stessa domanda prima di trovare questo articolo. La memoria latente tende ad attribuirsi più agli esempi che alla teoria, in generale.

0

Il blocco finally non può sempre essere eseguito, prendere in considerazione il seguente codice.

public class Tester { 
    public static void main(String[] args) { 
     try { 
      System.out.println("The main method has run"); 
      System.exit(1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      System.out.println("The finally block has run"); 
     } 
    } 
} 

Nel tuo caso, vorrei suggerire per avvolgere il codice all'interno blocco finally in try/catch, come il codice a quanto pare potrebbe generare un'eccezione.

} catch (SQLException sqle) { 
     sqle.printStackTrace(); 
    } finally { 
    try { 
     cs.close(); 
     rs.close(); 
    } catch (Exception e) { 
     //handle new exception here 
    } 
1

Se si cattura tutti gli errori, non ci dovrebbe nessuna differenza, in caso contrario, solo il codice all'interno blocco finally viene eseguito perché la sequenza di esecuzione di codice è: finalmente il codice -> errore di tiro -> codice dopo cattura di conseguenza, una volta il tuo codice genera un errore non gestito, solo alla fine il blocco di codice funziona come previsto.

2

Secondo HeadFirst Java, un blocco finally verrà eseguito anche se il blocco try o catch ha un'istruzione return. Flow salta infine e poi torna indietro.

+0

Questa risposta non aggiunge un singolo bit di informazioni che mancano alle altre risposte. – GhostCat

+0

Non sono d'accordo. Questa risposta è in realtà molto importante. La maggior parte delle risposte finora erano sbagliate, ma Aditi ha fornito un motivo chiave per cui a volte potresti voler usare "finalmente", quindi merita credito. – weiglt

Problemi correlati