Java 7: Autocloseable e Closeable Objects

DOMANDA:

Cosa sono gli oggetti AutoCloseable e Closeable?


RISPOSTA:

Java 7 ha introdotto una comoda caratteristica che è il try-with-resources di cui abbiamo parlato abbondantemente in questo post. Gli oggetti AutoCloseable e Closeable sono delle classi che implementano rispettivamente java.lang.AutoCloseable e java.io.Closeable. L'unico metodo che l'interfaccia obbliga ad implementare è il close(), chiamato alla fine del blocco try-with-resources.

Oltre a tutti gli oggetti che da Java 7 implementano già questa interfaccia, è possibile rendere le proprie classi "autochiudenti" semplicemente implementandola a nostra volta.

Guardiamo l'esempio:

package trywithresources;

public class PrimaRisorsa implements AutoCloseable{
   @Override
   public void close() throws Exception {
      System.out.println("CHIUDO PrimaRisorsa");
   }
}


E ora vediamo come funziona con un Test:

package trywithresources;

import java.io.IOException;

public class Test {
   public static void main(String[] args) throws IOException  {

      try (
         PrimaRisorsa sr = new PrimaRisorsa();
      ) {       
         System.out.println("AVVIO");
      } catch(Exception ex) {
         ex.printStackTrace();
         System.out.println("Eccezione nel try-with-resources");
      }
   }
}

L'output sarà:

AVVIO
CHIUDO PrimaRisorsa

Quindi il try-with-resources è riuscito a chiudere correttamente in automatico il nostro oggetto PrimaRisorsa.




Guardiamo ora cosa succede se dichiaro risorse multiple.

Creiamo una SecondaRisorsa (sempre autochiudente) che prenda come parametro del costruttore la PrimaRisorsa:

package trywithresources;

public class SecondaRisorsa implements AutoCloseable{

   public SecondaRisorsa(PrimaRisorsa s) {
       s = new PrimaRisorsa();
   }

   @Override
   public void close() throws Exception {
      System.out.println("CHIUDO SecondaRisorsa");
   }
}


Testiamo entrambe le risorse con Test2:

package trywithresources;

import java.io.IOException;

public class Test2 {
   public static void main(String[] args) throws IOException {

      try (
         PrimaRisorsa pr = new PrimaRisorsa();
         SecondaRisorsa sr = new SecondaRisorsa(new PrimaRisorsa());
      ) {

         System.out.println("AVVIO");

      } catch(Exception ex) {
         ex.printStackTrace();
         System.out.println("Eccezione nel try-with-resources");
      }
   }
}

L'output:

AVVIO
CHIUDO SecondaRisorsa
CHIUDO PrimaRisorsa


Notiamo subito che le risorse sono state chiuse in ordine inverso rispetto all'apertura (come è lecito aspettarsi) e soprattutto che l'autochiusura viene gestita in dal blocco try-with-resources solo per le risorse DICHIARATE. Per intenderci il "new PrimaRisorsa()" preso come parametro di SecondaRisorsa non viene preso in carico dal try-with-resources e lascia la responsabilità della chiusura all'oggetto che lo utilizza (quindi quello denominato sr nell'esempio).


Commenti

Post popolari in questo blog

Arrotondamento e troncamento in Java

Eclipse: Shortcuts (scorciatoie) da tastiera

Strutture dati: List, Set, Map

Creare un eseguibile Java