Ce face try-with-resources
Fișierele, conexiunile la baze de date și socket-urile trebuie închise după folosire, altfel rămân blocate resurse ale sistemului. În loc de un finally lung cu close() și verificări de null, declari resursele în parantezele lui try. La ieșirea din bloc, normal sau cu excepție, Java apelează automat close().
Merge cu orice obiect care implementează AutoCloseable (sau Closeable). Mai multe resurse se separă cu ; și se închid în ordine inversă deschiderii. Poți adăuga catch și finally, care rulează după închidere. Din Java 9 poți pune în paranteze și o variabilă deja declarată, dacă e efectiv finală.
Dacă și blocul, și close() aruncă excepții, se propagă cea din bloc, iar cea de la închidere este atașată ca „suprimată” (getSuppressed()), deci nu se pierde nicio informație.
Exemple
Exemplul 1: Scriere și citire de fișier
Writer-ul și reader-ul se închid automat la finalul fiecărui try. Fișierul note.txt se creează în directorul curent.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws IOException {
Path fisier = Path.of("note.txt");
try (BufferedWriter out = Files.newBufferedWriter(fisier)) {
out.write("Ana;9.50\n");
out.write("Bogdan;7.25\n");
out.write("Corina;10\n");
}
try (BufferedReader in = Files.newBufferedReader(fisier)) {
String linie;
while ((linie = in.readLine()) != null) {
String[] parti = linie.split(";");
System.out.println(parti[0] + " are nota " + parti[1]);
}
}
}
}
Rezultat
Ana are nota 9.50
Bogdan are nota 7.25
Corina are nota 10
Exemplul 2: Ordinea închiderii și o resursă proprie
Conexiune implementează AutoCloseable. Resursele se închid în ordine inversă (B, apoi A), înainte de catch și finally.
class Conexiune implements AutoCloseable {
private final String nume;
Conexiune(String nume) {
this.nume = nume;
System.out.println("deschid " + nume);
}
void trimite(String mesaj) {
if (mesaj.isEmpty()) {
throw new IllegalArgumentException("mesaj gol");
}
System.out.println(nume + " trimite: " + mesaj);
}
@Override
public void close() {
System.out.println("închid " + nume);
}
}
public class Main {
public static void main(String[] args) {
try (Conexiune a = new Conexiune("A"); Conexiune b = new Conexiune("B")) {
a.trimite("comanda 1024");
b.trimite("");
} catch (IllegalArgumentException e) {
System.out.println("catch: " + e.getMessage());
} finally {
System.out.println("finally");
}
}
}
Rezultat
deschid A
deschid B
A trimite: comanda 1024
închid B
închid A
catch: mesaj gol
finally
Exemplul 3: Excepții suprimate
Blocul aruncă o excepție și apoi și close() aruncă una. Se propagă prima, iar a doua apare în getSuppressed().
class Imprimanta implements AutoCloseable {
void tipareste(String doc) {
throw new IllegalStateException("hârtie blocată la " + doc);
}
@Override
public void close() {
throw new IllegalStateException("capacul nu se închide");
}
}
public class Main {
public static void main(String[] args) {
try (Imprimanta p = new Imprimanta()) {
p.tipareste("factura.pdf");
} catch (IllegalStateException e) {
System.out.println("principală: " + e.getMessage());
for (Throwable s : e.getSuppressed()) {
System.out.println("suprimată: " + s.getMessage());
}
}
}
}
Rezultat
principală: hârtie blocată la factura.pdf
suprimată: capacul nu se închide
Greșeli frecvente
- Deschizi fișierul fără
tryși uițiclose(); pe Windows fișierul rămâne blocat, iar la multe deschideri apareToo many open files. - Declari o resursă pe care nu o folosești în bloc:
-Xlintdă[try] auto-closeable resource x is never referenced in body of corresponding try statement. - Pui în paranteze un obiect care nu implementează
AutoCloseable:incompatible types: try-with-resources not applicable to variable type.
Comenzi înrudite
try, catch și finally: try încearcă un bloc de cod, catch prinde și tratează excepțiile aruncate în el, iar finally rulează mereu la ieșire.Excepții verificate și neverificate: Excepțiile verificate (Exception) trebuie prinse sau declarate cu throws; cele neverificate (RuntimeException) nu sunt cerute de compilator.throw și throws: throw aruncă o excepție acum; throws, în antetul metodei, anunță ce excepții verificate poate arunca metoda.Files: Clasa cu metode statice pentru lucrul cu fișiere și foldere: citire, scriere, copiere, mutare, ștergere, listare.BufferedReader: Citește text eficient, rând cu rând, dintr-un fișier, de la tastatură sau din alt Reader; close închide sursa.