ProgrammatieBackend ontwikkelaar

Wat is try-with-resources in Java, wat is het verschil met een klassieke try-catch-finally blok, en wanneer moet je het gebruiken?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

De belangrijkste taak van try-with-resources in Java is het automatisch en correct vrijgeven van bronnen. Voor de introductie van deze constructie in Java 7, moesten programmeurs bronnen handmatig sluiten in het finally blok. Dit leidde tot duplicatie van code en vaak fouten.

Geschiedenis van de kwestie

In Java 6 en eerder moesten bronnen (open bestanden, streams, verbindingen) handmatig worden beheerd via finally, wat vaak leidde tot lekken.

Probleem

Handmatig geschreven code voor het sluiten van bronnen is een bron van bugs, vooral bij het werken met meerdere uitzonderingen en een complexe hiërarchie van catch-blokken. Er is geen garantie dat close() wordt aangeroepen bij fouten.

Oplossing

Met Java 7 kwam de syntaxis try-with-resources, die een automatische aanroep van de methode close() garandeert voor elke bron die de interface AutoCloseable implementeert.

Voorbeeldcode:

try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) { String line = reader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } // reader wordt automatisch gesloten

Belangrijkste kenmerken:

  • Alle bronnen worden gegarandeerd gesloten, zelfs bij uitzonderingen.
  • Alleen objecten die de interface AutoCloseable implementeren kunnen worden gebruikt in try-with-resources.
  • De sjablooncode wordt vereenvoudigd en verkort, waardoor de kans op lekken wordt verminderd.

Vragen met een valstrik.

Vraag 1: Welke interface moet een bron implementeren voor try-with-resources?

AutoCloseable. Elk object dat deze interface (of Closeable) implementeert kan worden gebruikt in de constructie.

Vraag 2: In welke volgorde worden bronnen gesloten als er meerdere zijn in try-with-resources?

Bronnen worden in omgekeerde volgorde van hun verklaring gesloten (stack-LIFO):

try (A a = new A(); B b = new B()) { ... } // b.close() wordt als eerste aangeroepen, daarna a.close()

Vraag 3: Kan je try-with-resources gebruiken voor niet-standaard objecten, bijvoorbeeld voor een netwerkverbinding waarvoor geen implementatie van AutoCloseable bestaat?

Nee, maar je kunt AutoCloseable handmatig implementeren in je klasse. Daarna wordt het object compatibel met try-with-resources.

Typische fouten en anti-patronen

  • Vergeten om uitzonderingen af te handelen die in close() worden gegooid
  • Gebruik try-with-resources met klassen die AutoCloseable niet implementeren
  • Niet-gesloten bronnen in oude code, waar verouderde finally wordt toegepast

Voorbeeld uit het leven

Negatief geval

Ontwikkelaars sloten handmatig JDBC Connection en Statement via finally. Bij het optreden van een tweede uitzondering werd de sluiting van Statement niet uitgevoerd, de verbinding «bevroor» en verstopte de fout.

Voordelen:

  • Controle over de volgorde van sluiten.
  • Expliciet beheer van bronnen.

Nadelen:

  • Risico op vergeten om een bron te sluiten.
  • Verbindingen kunnen lekken.

Positief geval

Na de invoering van try-with-resources in de module voor het laden van bestanden worden alle streams automatisch gesloten, de code is veel korter geworden, en er zijn geen bugs met het lekken van bestanddescriptoren meer.

Voordelen:

  • Betrouwbaarheid.
  • Korte code.
  • Gemakkelijke tests.

Nadelen:

  • Vereiste implementatie van AutoCloseable.
  • Niet onmiddellijk beschikbaar in oudere versies van Java.