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.