In questo tutorial, impareremo l'istruzione try-with-resources per chiudere automaticamente le risorse.
L' try-with-resources
istruzione chiude automaticamente tutte le risorse alla fine dell'istruzione. Una risorsa è un oggetto da chiudere alla fine del programma.
La sua sintassi è:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Come visto dalla sintassi sopra, dichiariamo la try-with-resources
dichiarazione di,
- dichiarare e istanziare la risorsa all'interno della
try
clausola. - specificando e gestendo tutte le eccezioni che potrebbero essere generate durante la chiusura della risorsa.
Nota: l'istruzione try-with-resources chiude tutte le risorse che implementano l'interfaccia AutoCloseable.
Prendiamo un esempio che implementa l' try-with-resources
affermazione.
Esempio 1: prova con le risorse
import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) )
Output se il file test.txt non viene trovato.
IOException nel blocco try-with-resources => test.txt (Nessun file o directory di questo tipo)
Emissione se viene trovato il file test.txt.
Entrando nel blocco try-with-resources Line => test line
In questo esempio, utilizziamo un'istanza di BufferedReader per leggere i dati dal test.txt
file.
Dichiarare e creare un'istanza del BufferedReader all'interno try-with-resources
dell'istruzione garantisce che la sua istanza venga chiusa indipendentemente dal fatto che l' try
istruzione venga completata normalmente o generi un'eccezione.
Se si verifica un'eccezione, può essere gestita utilizzando i blocchi di gestione delle eccezioni o la parola chiave throws.
Eccezioni soppresse
Nell'esempio precedente, è possibile generare eccezioni dall'istruzione try-with-resources
quando:
- Il file
test.txt
non è stato trovato. - Chiusura
BufferedReader
dell'oggetto.
È inoltre possibile lanciare un'eccezione dal try
blocco poiché la lettura di un file può non riuscire per molti motivi in qualsiasi momento.
Se vengono generate eccezioni sia dal try
blocco che try-with-resources
dall'istruzione, try
viene generata l'eccezione dal blocco e l'eccezione try-with-resources
dall'istruzione viene soppressa.
Recupero delle eccezioni soppresse
In Java 7 e versioni successive, le eccezioni soppresse possono essere recuperate chiamando il Throwable.getSuppressed()
metodo dall'eccezione generata dal try
blocco.
Questo metodo restituisce una matrice di tutte le eccezioni soppresse. Otteniamo le eccezioni soppresse nel catch
blocco.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Vantaggi dell'utilizzo di try-with-resources
Ecco i vantaggi dell'utilizzo di try-with-resources:
1. infine blocco non necessario per chiudere la risorsa
Prima che Java 7 introducesse questa funzione, dovevamo usare il finally
blocco per assicurarci che la risorsa fosse chiusa per evitare perdite di risorse.
Ecco un programma simile all'Esempio 1 . Tuttavia, in questo programma, abbiamo utilizzato finalmente il blocco per chiudere le risorse.
Esempio 2: chiudere la risorsa utilizzando infine il blocco
import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) )
Produzione
Entrando in try block Line => line dal file test.txt Entrando infine in block
Come possiamo vedere dall'esempio sopra, l'uso di finally
block per ripulire le risorse rende il codice più complesso.
Notate anche il try… catch
blocco nel finally
blocco? Questo perché IOException
può verificarsi anche durante la chiusura BufferedReader
dell'istanza all'interno di questo finally
blocco, quindi viene anche catturata e gestita.
L' try-with-resources
istruzione esegue la gestione automatica delle risorse . Non è necessario chiudere esplicitamente le risorse poiché JVM le chiude automaticamente. Ciò rende il codice più leggibile e più facile da scrivere.
2. prova con risorse con più risorse
Possiamo dichiarare più di una risorsa try-with-resources
nell'istruzione separandole con un punto e virgola;
Esempio 3: prova con più risorse
import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) )
Se questo programma viene eseguito senza generare eccezioni, l' Scanner
oggetto legge una riga dal testRead.txt
file e la scrive in un nuovo testWrite.txt
file.
Quando vengono effettuate più dichiarazioni, l' try-with-resources
istruzione chiude queste risorse in ordine inverso. In questo esempio, l' PrintWriter
oggetto viene chiuso prima e poi l' Scanner
oggetto viene chiuso.
Miglioramento della prova con le risorse di Java 9
In Java 7, c'è una limitazione try-with-resources
all'istruzione. La risorsa deve essere dichiarata localmente all'interno del suo blocco.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Se avessimo dichiarato la risorsa fuori dal blocco in Java 7, avrebbe generato un messaggio di errore.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Per affrontare questo errore, Java 9 ha migliorato l' try-with-resources
istruzione in modo che il riferimento della risorsa possa essere utilizzato anche se non è dichiarato localmente. Il codice sopra verrà ora eseguito senza alcun errore di compilazione.