Java - Probeer met bronnen

1. Overzicht

Ondersteuning voor try-with-resources - geïntroduceerd in Java 7 - stelt ons in staat om aan te geven dat bronnen moeten worden gebruikt in een proberen blok met de zekerheid dat de bronnen zullen worden gesloten na de uitvoering van dat blok.

De gedeclareerde resources moeten het AutoCloseable koppel.

2. Met behulp van probeer-met-middelen

Simpel gezegd, om automatisch te worden gesloten, moet een bron zowel worden gedeclareerd als geïnitialiseerd binnen het proberen, zoals hieronder weergegeven:

probeer (PrintWriter-schrijver = nieuwe PrintWriter (nieuw bestand ("test.txt"))) {writer.println ("Hallo wereld"); } 

3. Vervangen proberenvangst-eindelijk Met probeer-met-middelen

De eenvoudige en voor de hand liggende manier om het nieuwe probeer-met-middelen functionaliteit is het vervangen van het traditionele en uitgebreide probeer-vangst-eindelijk blok.

Laten we de volgende codevoorbeelden vergelijken - de eerste is een typische probeer-vangst-eindelijk block, dan de nieuwe aanpak, met behulp van een gelijkwaardig try-with-resources-blok:

Scannerscanner = null; probeer {scanner = nieuwe scanner (nieuw bestand ("test.txt")); while (scanner.hasNext ()) {System.out.println (scanner.nextLine ()); }} catch (FileNotFoundException e) {e.printStackTrace (); } eindelijk {if (scanner! = null) {scanner.close (); }}

En hier is de super beknopte oplossing met behulp van try-with-resources:

probeer (Scanner scanner = nieuwe scanner (nieuw bestand ("test.txt"))) {while (scanner.hasNext ()) {System.out.println (scanner.nextLine ()); }} catch (FileNotFoundException fnfe) {fnfe.printStackTrace (); }

Hier kunt u het Scanner klasse.

4. probeer-met-middelen Met meerdere bronnen

Meerdere bronnen kunnen prima worden gedeclareerd in een probeer-met-middelen blok door ze te scheiden met een puntkomma:

probeer (Scanner scanner = nieuwe scanner (nieuw bestand ("testRead.txt")); PrintWriter writer = nieuwe PrintWriter (nieuw bestand ("testWrite.txt"))) {while (scanner.hasNext ()) {writer.print ( scanner.nextLine ()); }}

5. Een aangepaste bron met AutoCloseable

Om een ​​aangepaste bron te maken die correct wordt afgehandeld door een probeer-met-middelen block, moet de klasse het Afsluitbaar of AutoCloseable interfaces, en overschrijf de dichtbij methode:

openbare klasse MyResource implementeert AutoCloseable {@Override public void close () gooit Uitzondering {System.out.println ("Gesloten MyResource"); }}

6. Afsluitingsopdracht voor resources

Bronnen die als eerste zijn gedefinieerd / verworven, worden als laatste gesloten; laten we eens kijken naar een voorbeeld van dit gedrag:

Bron 1:

openbare klasse AutoCloseableResourcesFirst implementeert AutoCloseable {openbare AutoCloseableResourcesFirst () {System.out.println ("Constructor -> AutoCloseableResources_First"); } public void doSomething () {System.out.println ("Something -> AutoCloseableResources_First"); } @Override public void close () gooit uitzondering {System.out.println ("Closed AutoCloseableResources_First"); }} 

Bron 2:

openbare klasse AutoCloseableResourcesSecond implementeert AutoCloseable {openbare AutoCloseableResourcesSecond () {System.out.println ("Constructor -> AutoCloseableResources_Second"); } public void doSomething () {System.out.println ("Something -> AutoCloseableResources_Second"); } @Override public void close () gooit uitzondering {System.out.println ("Gesloten AutoCloseableResources_Second"); }}

Code:

private void orderOfClosingResources () gooit uitzondering {try (AutoCloseableResourcesFirst af = nieuwe AutoCloseableResourcesFirst (); AutoCloseableResourcesSecond as = nieuwe AutoCloseableResourcesSecond ()) {af.doSomething (); as.doSomething (); }} 

Uitgang:

Constructor -> AutoCloseableResources_First

Constructor -> AutoCloseableResources_Second

Iets -> AutoCloseableResources_First

Iets -> AutoCloseableResources_Second

Gesloten AutoCloseableResources_Second

Gesloten AutoCloseableResources_First

7. vangst & Tenslotte

EEN probeer-met-middelen blok kan nog steeds de vangst en Tenslotte blokken - die op dezelfde manier werkt als bij een traditionele proberen blok.

8. Java 9: ​​effectief definitiefVariabelen

Vóór Java 9 konden we alleen verse variabelen gebruiken in een probeer-met-middelen blok:

probeer (Scanner scanner = nieuwe scanner (nieuw bestand ("testRead.txt")); PrintWriter-schrijver = nieuwe PrintWriter (nieuw bestand ("testWrite.txt"))) {// weggelaten}

Zoals hierboven getoond, was dit vooral uitgebreid bij het declareren van meerdere bronnen. Vanaf Java 9 en als onderdeel van JEP 213, we kunnen nu gebruiken laatste of zelfs effectief laatste variabelen binnen een probeer-met-middelen blok:

definitieve scanner scanner = nieuwe scanner (nieuw bestand ("testRead.txt")); PrintWriter-schrijver = nieuwe PrintWriter (nieuw bestand ("testWrite.txt")) probeer (scanner; schrijver) {// weggelaten}

Simpel gezegd, een variabele is in feite definitief als deze niet verandert na de eerste toewijzing, ook al is deze niet expliciet gemarkeerd als laatste.

Zoals hierboven getoond, is de scanner variabele is gedeclareerd laatste expliciet, zodat we het kunnen gebruiken met de probeer-met-middelen blok. Hoewel de auteur variabele is niet expliciet laatste, het verandert niet na de eerste opdracht. Daarom mogen we de auteur ook variabel.

9. Conclusie

In dit artikel hebben we besproken hoe u try-with-resources kunt gebruiken, hoe u deze kunt vervangen proberen, vangst, en Tenslotte met try-with-resources, aangepaste resources bouwen met AutoCloseable en de volgorde waarin bronnen worden gesloten.

Het complete broncode voor het voorbeeld is beschikbaar in dit GitHub-project.