2013-08-07 9 views
7

che è meglio per blocco finally:Chiudere la connessione e la dichiarazione, infine

finally { 
     try { 
      con.close(); 
      stat.close(); 
     } catch (SQLException sqlee) { 
      sqlee.printStackTrace(); 
     } 
    } 

Oppure:

finally { 
     try { 
      if (con != null) { 
       con.close(); 
      } 
      if (stat != null) { 
       stat.close(); 
      } 
     } catch (SQLException sqlee) { 
      sqlee.printStackTrace(); 
     } 
    } 
+0

Ebbene, dal momento che il primo avrebbe gettato un NPE ... –

+0

Si dovrebbe chiudere la dichiarazione prima del collegamento. –

+0

@MarkRotteveel bella nota, puoi dirmi perché? – Sajad

risposta

15

modo migliore per utilizzare è il 2 ° uno, perché se viene generata un'eccezione durante l'inizializzazione con o stat, non verranno inizializzati e potrebbero essere inizializzati su null. In tal caso, l'utilizzo del 1 ° codice genererà NullPointerException.

Inoltre, se si è già in Java 7, si dovrebbe considerare l'utilizzo di try-with-resources, che chiude automaticamente le risorse. Dal tutorial collegato:

L'istruzione try-with-resources garantisce che ogni risorsa sia chiusa alla fine dell'istruzione. Qualsiasi oggetto che implementa java.lang.AutoCloseable, che include tutti gli oggetti che implementano java.io.Closeable, può essere utilizzato come risorsa.

+0

@Sajjad. Clicca sul link nella risposta. Questo è il tutorial su oracle di try-with-resources. Puoi attraversarlo. –

+0

Ok, possiamo dire che questo 'try-with-resources' è più semplice della vecchia maniera? Perché la specifica del tipo di eccezione è automatica e non è necessario catturare il blocco? – Sajad

+0

@Sajjad. È più semplice nel senso, non devi preoccuparti di chiudere nessuna risorsa che stai usando lì. Ma devi comunque fornire un blocco 'catch'. –

0

Se c'è una possibilità o è null, è necessario verificare che. Se la possibilità non esiste, non vi è alcun motivo valido per verificarlo.

Inoltre, è possibile rendere il codice un po 'meglio leggibile omettendo alcune staffe singola istruzione:

finally { 
    try { 
     if (con != null) 
      con.close(); 

     if (stat != null) 
      stat.close(); 

    } catch (SQLException sqlee) { 
     sqlee.printStackTrace(); 
    } 
} 
+2

Sebbene preferisca la preferenza personale, non mi piace l'omissione delle parentesi per le singole affermazioni. Soprattutto, quando contengono più dichiarazioni singole senza parentesi. Trovo molto più difficile leggere il codice, e quando il rientro è incoerente la leggibilità viene ulteriormente ridotta. – Muel

0

Vorrei andare con la seconda opzione, ma l'aggiunta di un secondo blocco nidificato finally, solo per assicurarsi che entrambi i con e stat oggetti sono contrassegnati per la raccolta dei rifiuti:

finally { 
    try { 
     if(con != null) 
      con.close(); 
     if(stat != null) 
      stat.close(); 
    } catch(SQLException sqlee) { 
     sqlee.printStackTrace(); 
    } finally { // Just to make sure that both con and stat are "garbage collected" 
     con = null; 
     stat = null; 
    } 
} 
6

Nessuno di loro sono buoni abbastanza. Utilizzare questa:

public static void closeQuietly(AutoCloseable ... closeables) { 
    for (AutoCloseable c : closeables) { 
     if (c != null) { 
      try { 
       c.close(); 
      } catch (Exception e) { 
       // log or ignore, we can't do anything about it really 
      } 
     } 
    } 
} 

e chiamarlo come closeQuietly(stat, con);

Oppure utilizzare Java 7 del try-with-resource:

List<String> results = new ArrayList<>(); 
    try (Statement statement = conn.createStatement(); 
     ResultSet rs = statement.executeQuery(query)) { 

     int numberOfColumns = getColumnCount(rs); 
     while (rs.next()) { 
      int i = 1; 
      while (i <= numberOfColumns) { 
       results.add(rs.getString(i++)); 
      } 
     } 
    } 
+0

Un bel approccio! Ma continuo a pensare che un blocco 'finally' (che imposta ogni' c = null; ') sia desiderabile. – Barranka

+0

Non dovresti impostare manualmente campi/variabili su null per "notificare" il GC a meno che l'ambito non sia lungo. Nell'esempio sopra stiamo parlando di un millisecondo o meno e il guadagno è basso (se presente). – Xabster

+0

Ho risposto a questo troppo ampio. Nell'esempio sopra, i riferimenti originali a Connection e Statement esistono ancora al di fuori di questo metodo (chiunque abbia chiamato il metodo ha ancora i riferimenti originali) e dovremmo semplicemente annullare le copie dei riferimenti passati al nostro metodo. – Xabster

4

Come di Java 7, non hai bisogno di più utilizzare il blocco finallyl per chiudere un oggetto Connection o Statement. Invece puoi utilizzare le nuove funzionalità chiamate "try-with-resources".

In primo luogo si dichiara una connessione e Statament oggetti utilizzando la nuova sintassi per un blocco try-catch come segue:

try(Connection con = DriverManager.getConnection(database-url, user, password); Statement st = conn.createStatement()) { 

//your stuffs here 
} catch (SQLException e) { 
    e.printStackTrace(); 
}  

In questo modo, non sarà necessario preoccuparsi di chiudere in modo esplicito il legame con la database in un blocco finale perché jvm lo farà per te.

ha belle codifica ....