Java - Опитайте с ресурси

1. Общ преглед

Поддръжката за try-with-resources - въведена в Java 7 - ни позволява да декларираме ресурси, които да бъдат използвани в блок try, с увереността, че ресурсите ще бъдат затворени след изпълнението на този блок.

Декларираните ресурси трябва да изпълняват интерфейса AutoCloseable .

2. Използване на опит с ресурси

Просто казано, за да се затвори автоматично, ресурсът трябва да бъде деклариран и инициализиран в опита , както е показано по-долу:

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) { writer.println("Hello World"); } 

3. Замяна на try - catch-final с try-with-resources

Простият и очевиден начин за използване на новата функционалност try-with-resources е да замените традиционния и многословен блок try-catch- final.

Нека сравним следните примерни кодове - първо е типичен блок try-catch- final, след това новият подход, използвайки еквивалентен блок try-with-resources:

Scanner scanner = null; try { scanner = new Scanner(new File("test.txt")); while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (scanner != null) { scanner.close(); } }

И ето супер краткото решение, използващо try-with-resources:

try (Scanner scanner = new Scanner(new File("test.txt"))) { while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); }

Ето къде можете да проучите допълнително класа на скенера .

4. опитайте с ресурси с множество ресурси

Множество ресурси могат да бъдат декларирани добре в блок try-with-resources, като ги разделите с точка и запетая:

try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); } }

5. Персонализиран ресурс с автоматично затваряне

За да се създаде персонализиран ресурс, който ще се обработва правилно от блок try-with-resources , класът трябва да реализира интерфейсите Closeable или AutoCloseable и да замени метода close :

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

6. Ред за затваряне на ресурс

Ресурсите, които бяха дефинирани / придобити първи, ще бъдат затворени последни; нека разгледаме пример за това поведение:

Ресурс 1:

public class AutoCloseableResourcesFirst implements AutoCloseable { public AutoCloseableResourcesFirst() { System.out.println("Constructor -> AutoCloseableResources_First"); } public void doSomething() { System.out.println("Something -> AutoCloseableResources_First"); } @Override public void close() throws Exception { System.out.println("Closed AutoCloseableResources_First"); } } 

Ресурс 2:

public class AutoCloseableResourcesSecond implements AutoCloseable { public AutoCloseableResourcesSecond() { System.out.println("Constructor -> AutoCloseableResources_Second"); } public void doSomething() { System.out.println("Something -> AutoCloseableResources_Second"); } @Override public void close() throws Exception { System.out.println("Closed AutoCloseableResources_Second"); } }

Код:

private void orderOfClosingResources() throws Exception { try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst(); AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) { af.doSomething(); as.doSomething(); } } 

Изход:

Конструктор -> AutoCloseableResources_First

Конструктор -> AutoCloseableResources_Second

Нещо -> AutoCloseableResources_First

Нещо -> AutoCloseableResources_Second

Затворено AutoCloseableResources_Second

Затворено AutoCloseableResources_First

7. улов & накрая

А пробвам-с-ресурси блок все още може да има улов и накрая блокове - което ще работи по същия начин, както с традиционен опит блок.

8. Java 9: ​​Ефективно окончателенПроменливи

Преди Java 9 можехме да използваме само променливи в блока try-with-resources :

try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { // omitted }

Както беше показано по-горе, това беше особено многословно при деклариране на множество ресурси. От Java 9 и като част от JEP 213, вече можем да използваме окончателни или дори ефективно окончателни променливи в блока try-with-resources :

final Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt")) try (scanner;writer) { // omitted }

Казано по-просто, променлива е ефективно окончателна, ако не се промени след първото задание, въпреки че не е изрично маркирана като окончателна .

Както е показано по-горе, променливата на скенера е декларирана изрично окончателно , така че можем да я използваме с блока try-with-resources . Въпреки че променливата на писателя не е изрично окончателна, тя не се променя след първото задание. Следователно ни е позволено да използваме и променливата писател .

9. Заключение

В тази статия обсъдихме как да използваме try-with-resources, как да заменим try , catch и накрая с try-with-resources, изграждайки персонализирани ресурси с AutoCloseable и ред, в който ресурсите се затварят.

Пълният изходен код за примера е наличен в този проект на GitHub.