Ho il codice seguente:
public class Main { public static void main(String[] args) throws SQLException { try ( Connection conn = DBUtil.getConnection(DBType.HSQLDB); Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet rs = stmt.executeQuery("SELECT * FROM tours"); ) { DBUtil.getConnection(); } catch (SQLException e) { DBUtil.processException(e); } } }
Io uso questo codice per recuperare i dati da un database. Il mio problema è che non mi è permesso usare il compilatore Java 1.7 e devo usare 1.6. Come posso tradurre il codice try-with-resources da utilizzare con un compilatore 1.6? Cosa succede esattamente in questo blocco di prova speciale?
Oracle spiega come funziona try-with-resources qui
Il TL; DR di esso è:
Non c’è un modo semplice per farlo in Java 1.6. Il problema è l’assenza del campo Soppresso in Eccezione. Puoi ignorarlo e hardcode cosa succede quando entrambi provano AND chiudi diverse eccezioni o crea la tua sottocerella di eccezione che ha il campo soppresso.
Nel secondo caso, il link sopra dà il modo corretto di farlo:
AutoClose autoClose = new AutoClose(); MyException myException = null; try { autoClose.work(); } catch (MyException e) { myException = e; throw e; } finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); } }
è equivalente a
try (AutoClose autoClose = new AutoClose()) { autoClose.work(); }
Nel caso in cui si desideri semplificare e non creare un sacco di nuove classi di eccezioni, sarà necessario decidere cosa inserire nella clausola catch all’interno di finally (t oe).
PS. Trattare con più dichiarazioni variabili nel tentativo è anche discusso nel link sopra. E la quantità di codice necessaria per farlo correttamente è sbalorditiva. La maggior parte delle persone prende scorciatoie in Java 1.6 non gestendo eccezioni nel blocco finally e usando nullcheck.
Fai cosi:
Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = DBUtil.getConnection(DBType.HSQLDB); stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs = stmt.executeQuery("SELECT * FROM tours"); } catch (SQLException e) { DBUtil.processException(e); } finally { if(conn != null) { conn.close(); } if(stmt != null) { stmt.close(); } if(rs != null) { rs.close(); } }
Vorrei consigliare l’uso della libreria di commons-dbutils di apache che ha classi DBUtils
con metodi close
e closeQuietly
. Il codice sarebbe simile a questo:
import org.apache.commons.dbutils.DBUtils; ... Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = myOwnUtil.getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery( "SELECT * FROM table" ); // or any other custom query } catch ( SQLException e ) { <>; } finally { DBUtils.closeQuietly( conn ); DBUtils.closeQuietly( stmt ); DBUtils.closeQuietly( rs ); // or simply use DBUtils.close( conn, stmt, rs ); }
Nota che closeQuietly non farà eccezione, mentre chiudi potrebbe lanciare SQLException, quindi adatta il codice al tuo caso d’uso.
Se vuoi chiudere i flussi di quanto tu possa usare apache’s commons-io con la class IOUtils che ha anche close e closeQuietly.