Java try-with-resources (z przykładami)

W tym samouczku nauczymy się instrukcji try-with-resources, aby automatycznie zamknąć zasoby.

try-with-resourcesOświadczenie automatycznie zamyka wszystkie zasoby na końcu instrukcji. Zasób to obiekt, który ma zostać zamknięty na końcu programu.

Jego składnia to:

 try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block ) 

Jak widać z powyższej składni, deklarujemy try-with-resourcesinstrukcję przez,

  1. deklarowanie i tworzenie wystąpienia zasobu w tryklauzuli.
  2. określanie i obsługa wszystkich wyjątków, które mogą zostać zgłoszone podczas zamykania zasobu.

Uwaga: Instrukcja try-with-resources zamyka wszystkie zasoby, które implementują interfejs AutoCloseable.

Weźmy przykład, który implementuje try-with-resourcesinstrukcję.

Przykład 1: try-with-resources

 import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) ) 

Dane wyjściowe, jeśli nie znaleziono pliku test.txt.

 IOException w try-with-resources block => test.txt (Brak takiego pliku lub katalogu) 

Dane wyjściowe, jeśli zostanie znaleziony plik test.txt.

 Wprowadzanie bloku try-with-resources Line => test line 

W tym przykładzie używamy wystąpienia BufferedReader do odczytu danych z test.txtpliku.

Deklarowanie i tworzenie wystąpienia BufferedReader wewnątrz try-with-resourcesinstrukcji zapewnia, że ​​jego wystąpienie zostanie zamknięte, niezależnie od tego, czy tryinstrukcja kończy się normalnie, czy zgłasza wyjątek.

Jeśli wystąpi wyjątek, można go obsłużyć za pomocą bloków obsługi wyjątków lub słowa kluczowego throws.

Stłumione wyjątki

W powyższym przykładzie wyjątki można wyrzucić z try-with-resourcesinstrukcji, gdy:

  • Plik test.txtnie został znaleziony.
  • Zamknięcie BufferedReaderobiektu.

Z trybloku można również wyrzucić wyjątek, ponieważ odczyt pliku może się nie powieść z wielu powodów w dowolnym momencie.

Jeśli wyjątki są generowane zarówno z trybloku, jak i try-with-resourcesinstrukcji, zostanie zgłoszony wyjątek z trybloku, a wyjątek z try-with-resourcesinstrukcji zostanie pominięty.

Pobieranie wyłączonych wyjątków

W Javie 7 i nowszych wersjach pominięte wyjątki można pobrać, wywołując Throwable.getSuppressed()metodę z wyjątku zgłoszonego przez tryblok.

Ta metoda zwraca tablicę wszystkich pominiętych wyjątków. Otrzymujemy wyłączone wyjątki w catchbloku.

 catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) ) 

Zalety korzystania z zasobów „try-with-resources”

Oto zalety korzystania z zasobów typu Try-with-Resources:

1. ostatecznie blok nie jest wymagany do zamknięcia zasobu

Zanim Java 7 wprowadziła tę funkcję, musieliśmy użyć finallybloku, aby upewnić się, że zasób jest zamknięty, aby uniknąć wycieków zasobów.

Oto program podobny do przykładu 1 . Jednak w tym programie ostatecznie użyliśmy bloku do zamknięcia zasobów.

Przykład 2: Zamknij zasób za pomocą final block

 import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) ) 

Wynik

 Wchodzenie do try block Line => line z pliku test.txt Wchodzenie na koniec blok 

Jak widać z powyższego przykładu, użycie finallybloku do czyszczenia zasobów sprawia, że ​​kod jest bardziej złożony.

Zwróć uwagę na try… catchblok w finallybloku? Dzieje się tak, ponieważ IOExceptionmoże również wystąpić podczas zamykania BufferedReaderinstancji w tym finallybloku, więc jest ona również przechwytywana i obsługiwana.

try-with-resourcesOświadczenie robi automatyczne zarządzanie zasobami . Nie musimy jawnie zamykać zasobów, ponieważ JVM automatycznie je zamyka. Dzięki temu kod jest bardziej czytelny i łatwiejszy do napisania.

2. spróbuj z zasobami z wieloma zasobami

W try-with-resourcesinstrukcji możemy zadeklarować więcej niż jeden zasób, oddzielając je średnikiem;

Przykład 3: spróbuj z wieloma zasobami

 import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) ) 

Jeśli ten program jest wykonywany bez generowania żadnych wyjątków, Scannerobiekt odczytuje wiersz z testRead.txtpliku i zapisuje go w nowym testWrite.txtpliku.

W przypadku wielu deklaracji try-with-resourcesinstrukcja zamyka te zasoby w odwrotnej kolejności. W tym przykładzie PrintWriterobiekt jest najpierw zamykany, a następnie Scannerzamykany.

Ulepszenie próbowania z zasobami Java 9

W Javie 7 występuje ograniczenie do try-with-resourcesinstrukcji. Zasób należy zadeklarować lokalnie w swoim bloku.

 try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code ) 

Gdybyśmy zadeklarowali zasób poza blokiem w Javie 7, wygenerowałoby to komunikat o błędzie.

 Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code ) 

Aby poradzić sobie z tym błędem, Java 9 poprawiła try-with-resourcesinstrukcję, tak aby można było użyć odwołania do zasobu, nawet jeśli nie jest zadeklarowane lokalnie. Powyższy kod będzie teraz wykonywany bez błędu kompilacji.

Interesujące artykuły...