A partire dalla versione 7, Java offre una migliore gestione delle risorse che dovrebbero essere chiuse una volta terminato di utilizzarle. Tali risorse includono, ad esempio, file, flussi, connessioni a database e socket. Questo scopo è servito da uno speciale costrutto linguistico try-with-resources. Affinché questa chiusura automatica funzioni, è stata creata un'interfaccia speciale
AutoCloseable
. In Java 7, tutte le classi di risorse implementano questa interfaccia. La sua firma è simile a questa:
public interface AutoCloseable {
void close() throws Exception;
}
L'interfaccia dichiara un metodo close()
che viene automaticamente chiamato sugli oggetti serviti dal costrutto try-with-resources
. Sebbene le classi di risorse in Java 7 implementino questa interfaccia, molte delle librerie che utilizzi non lo fanno, perché la libreria non è stata ancora aggiornata per funzionare con l' interfaccia AutoCloseable o semplicemente non hai la possibilità di aggiornare la libreria. Nella maggior parte dei casi questo può essere facilmente risolto. Eredita la classe di risorse che dovrebbe partecipare al progetto try-with-resources
. Prendiamo ad esempio ITextRenderer
(dal progetto Flying Saucer). Dopo aver finito di lavorare con ITextRenderer
, il metodo dovrebbe essere chiamato finishPDF()
. Normalmente lo faresti in un blocco finally
. Ma quando crei una nuova classe che estende ITextRenderer
e implementa l'interfaccia AutoCloseable
, puoi includerla nel file try-with-resources
. La nuova classe AutoCloseableITextRenderer
sarà simile a questa:
public class AutoCloseableITextRenderer extends ITextRenderer implements AutoCloseable {
@Override
public void close() {
super.finishPDF();
}
}
Estendere la classe originale in un discendente è la soluzione più ragionevole, poiché la nuova classe sarà ancora ITextRenderer
. Nel caso in cui la classe originale sia dichiarata come final
, è necessario utilizzare la composizione. E questo è come sarebbe l'utilizzo:
try (final AutoCloseableITextRenderer iTextRenderer = new AutoCloseableITextRenderer()) {
ByteArrayOutputStream out; // contains the data to be converted to PDF, not shown here.
iTextRenderer.setDocumentFromString(new String(out.toByteArray()));
iTextRenderer.layout();
iTextRenderer.createPDF(pdfOutputStream);
pdfOutputStream.flush();
}
È tutto. Tieni presente che non ho generato un'eccezione da un metodo close()
nel file AutoCloseableITextRenderer
. Il Javadoc dell'interfaccia AutoCloseable
dice quanto segue a questo proposito: Sebbene il metodo dell'interfaccia sia dichiarato per lanciare eccezioni Exception
, si consiglia vivamente agli implementatori di questo metodo di utilizzare classi di eccezioni più specifiche durante l'implementazione del metodo o di non lanciare affatto eccezioni se il metodo close()
non può fallire.
GO TO FULL VERSION