Perché usare finalmente invece del codice dopo la cattura

Perché farlo

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

Invece di questo

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

Perché se un’eccezione non viene lanciata nessun codice dopo che il blocco try viene eseguito a meno che non venga rilevata l’eccezione. Un blocco finally viene sempre eseguito indipendentemente da ciò che accade all’interno del blocco try .

Guarda il tuo blocco di cattura: sta per lanciare DAOException . Quindi le istruzioni dopo il blocco catch non verranno eseguite nemmeno nell’esempio che hai fornito . 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 esempio perché una delle chiamate che effettua non riesce.

Inoltre, potrebbero non esserci altre eccezioni che non vengono rilevate, perché hai dichiarato che il metodo le ha generate o perché sono eccezioni non controllate. Vuoi veramente perdere risorse perché una IllegalArgumentException stata lanciata da qualche parte?

Perché se viene lanciata un’eccezione,

  • Il codice nella clausola finally verrà eseguito mentre 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 verrà eseguito a meno che l’eccezione non venga catturata da un blocco catch e non ricalcasting.

Perché garantisce che le cose nel blocco finally vengano eseguite. Stuff after catch potrebbe non essere eseguito, ad esempio, c’è un’altra eccezione nel blocco catch, che è molto ansible. Oppure fai semplicemente ciò che hai fatto e genera un’eccezione che racchiude l’eccezione originale.

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.

La parola chiave finally garantisce che il codice sia eseguito. Nell’esempio in basso, le dichiarazioni di chiusura NON sono eseguite. Nell’esempio in alto, vengono eseguiti (cosa vuoi!)

Il tuo secondo approccio non farà le dichiarazioni di “chiusura” perché è già stato lasciato il metodo.

Se rilevi tutti gli errori, non dovrebbe esserci differenza, altrimenti, solo il codice all’interno di finally block viene eseguito perché la sequenza di esecuzione del codice è: finally code -> error throw -> code after catch quindi, una volta che il tuo codice lancia un errore non gestito, solo alla fine il blocco di codice funziona come previsto.

Questo è il modo per evitare perdite di risorse

Il codice nel blocco finally verrà chiamato prima che l’eccezione venga rimossa 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.

considerare che il catch 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.

In http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html questo è fuorviante (e potrebbe aver originato la domanda):

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. 

Manca la quarta via (viene generata un’eccezione diversa da IOException e IndexOutOfBoundsException ). Il codice illustrato nella pagina precedente cattura solo (1) e (2) prima di ricorrere finally .

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

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, suggerirei di racchiudere il codice all’interno di finally block in try / catch, poiché questo codice apparentemente potrebbe generare un’eccezione.

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