Java try-with-resources (Với các ví dụ)

Trong hướng dẫn này, chúng ta sẽ tìm hiểu về câu lệnh try-with-resources để tự động đóng tài nguyên.

Câu try-with-resourceslệnh tự động đóng tất cả các tài nguyên ở cuối câu lệnh. Tài nguyên là một đối tượng được đóng ở cuối chương trình.

Cú pháp của nó là:

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

Như đã thấy từ cú pháp trên, chúng tôi khai báo try-with-resourcescâu lệnh bằng,

  1. khai báo và khởi tạo tài nguyên trong trymệnh đề.
  2. xác định và xử lý tất cả các ngoại lệ có thể được ném ra khi đóng tài nguyên.

Lưu ý: Câu lệnh try-with-resources đóng tất cả các tài nguyên triển khai giao diện AutoClosable.

Hãy để chúng tôi lấy một ví dụ thực hiện try-with-resourcescâu lệnh.

Ví dụ 1: thử tài nguyên

 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()); ) ) ) 

Kết quả nếu không tìm thấy tệp test.txt.

 IOException trong khối try-with-resources => test.txt (Không có tệp hoặc thư mục như vậy) 

Xuất ra nếu tệp test.txt được tìm thấy.

 Nhập dòng khối try-with-resources => dòng kiểm tra 

Trong ví dụ này, chúng tôi sử dụng một phiên bản của BufferedReader để đọc dữ liệu từ test.txttệp.

Khai báo và khởi tạo BufferedReader bên trong try-with-resourcescâu lệnh đảm bảo rằng thể hiện của nó được đóng bất kể trycâu lệnh hoàn thành bình thường hay ném một ngoại lệ.

Nếu một ngoại lệ xảy ra, nó có thể được xử lý bằng cách sử dụng các khối xử lý ngoại lệ hoặc từ khóa ném.

Ngoại lệ bị triệt tiêu

Trong ví dụ trên, các ngoại lệ có thể được ném ra khỏi try-with-resourcescâu lệnh khi:

  • Tệp test.txtkhông được tìm thấy.
  • Đang đóng BufferedReaderđối tượng.

Một ngoại lệ cũng có thể được ném ra khỏi trykhối vì quá trình đọc tệp có thể không thành công vì nhiều lý do bất kỳ lúc nào.

Nếu các ngoại lệ được ném ra từ cả trykhối và try-with-resourcescâu lệnh, thì ngoại lệ từ trykhối được ném ra và ngoại lệ từ try-with-resourcescâu lệnh bị loại bỏ.

Truy xuất các ngoại lệ bị loại bỏ

Trong Java 7 trở lên, các ngoại lệ bị chặn có thể được truy xuất bằng cách gọi Throwable.getSuppressed()phương thức từ ngoại lệ do trykhối ném ra .

Phương thức này trả về một mảng tất cả các ngoại lệ bị loại bỏ. Chúng tôi nhận được các ngoại lệ bị đàn áp trong catchkhối.

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

Ưu điểm của việc sử dụng thử tài nguyên

Dưới đây là những lợi ích của việc sử dụng thử với tài nguyên:

1. cuối cùng khối không cần thiết để đóng tài nguyên

Trước khi Java 7 giới thiệu tính năng này, chúng ta phải sử dụng finallykhối để đảm bảo rằng tài nguyên được đóng lại để tránh rò rỉ tài nguyên.

Đây là một chương trình tương tự như Ví dụ 1 . Tuy nhiên, trong chương trình này, chúng tôi đã sử dụng khối cuối cùng để đóng tài nguyên.

Ví dụ 2: Đóng tài nguyên bằng khối cuối cùng

 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()); ) ) ) ) 

Đầu ra

 Nhập thử khối Dòng => dòng từ tệp test.txt Nhập khối cuối cùng 

Như chúng ta có thể thấy từ ví dụ trên, việc sử dụng finallykhối để dọn dẹp tài nguyên làm cho mã phức tạp hơn.

Chú ý cả try… catchkhối trong finallykhối? Điều này là do một IOExceptioncũng có thể xảy ra trong khi đóng BufferedReadercá thể bên trong finallykhối này nên nó cũng bị bắt và xử lý.

Câu try-with-resourceslệnh thực hiện quản lý tài nguyên tự động . Chúng tôi không cần đóng tài nguyên một cách rõ ràng vì JVM tự động đóng chúng. Điều này làm cho mã dễ đọc hơn và dễ viết hơn.

2. thử tài nguyên với nhiều tài nguyên

Chúng ta có thể khai báo nhiều tài nguyên trong try-with-resourcescâu lệnh bằng cách phân tách chúng bằng dấu chấm phẩy;

Ví dụ 3: thử với nhiều tài nguyên

 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()); ) ) ) ) 

Nếu chương trình này thực thi mà không tạo ra bất kỳ ngoại lệ nào, Scannerđối tượng sẽ đọc một dòng từ testRead.txttệp và ghi nó vào một testWrite.txttệp mới .

Khi nhiều khai báo được thực hiện, try-with-resourcescâu lệnh đóng các tài nguyên này theo thứ tự ngược lại. Trong ví dụ này, PrintWriterđối tượng được đóng trước và sau đó Scannerđối tượng được đóng lại.

Nâng cao tính năng thử với tài nguyên trong Java 9

Trong Java 7, có một hạn chế đối với try-with-resourcescâu lệnh. Tài nguyên cần được khai báo cục bộ trong khối của nó.

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

Nếu chúng ta khai báo tài nguyên bên ngoài khối trong Java 7, nó sẽ tạo ra một thông báo lỗi.

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

Để đối phó với lỗi này, Java 9 đã cải thiện try-with-resourcescâu lệnh để tham chiếu của tài nguyên có thể được sử dụng ngay cả khi nó không được khai báo cục bộ. Đoạn mã trên bây giờ sẽ thực thi mà không có bất kỳ lỗi biên dịch nào.

thú vị bài viết...