- vừa được xem lúc

Prefer try-with-resources to try-finally

0 0 20

Người đăng: sang lam

Theo Viblo Asia

Prefer try-with-resources to try-finally

I. Vấn đề

  • Rất nhiều trường hợp khi sử dụng tài nguyên từ các lib trong java rồi lại quên close nó, dẫn tới ảnh hưởng nhiều tới việc xử dụng resource lãng phí, performance lại bị giảm, nếu trong những ứng dụng lớn còn có thể crash. Có thể thấy những ví dụ tiêu biểu như I/O stream, database connection của JDBC,... là những lib được sử dụng nhiều nên cũng thường quên phải close khi sử dụng xong. Một trong những cách đảm bảo chúng được close sau khi sử dụng là đặt nó vào khối Finally
 static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } }

Nhìn cũng khá là bình thường như bao xử lý khác, thế thì tiếp tục nhìn xuống ví dụ tiếp theo:

 static void copy(String src, String destination) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(destination); try{ int n; byte [] buf = new byte[BUFFER_SIZE]; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } } finally { in.close(); } }
  • Trước hết chưa bàn tới tính đúng sai, cái source này mà đưa cho thằng em bá đạo nó đọc, xong viết UT là nó chửi thôi rồi (😆😆😆).
  • Mặc dù source ở trên vẫn được chạy đúng, cover được các resources được sử dụng với khối Try-finally. Tuy nhiên hãy tưởng tượng khi xảy ra exception trong và ngoài khối finally và bạn lại muốn debug, lần theo dấu vết của chúa để tìm nguyên nhân thì sẽ gặp vấn đề ở đây.

Trước hết nhìn vào function firstLineOfFile

- Giả sử rằng readline có thể trả về exception vì trong thể tìm thấy resource ở trong path, và close trong block Finally cũng tương tự.
- Lúc này exception thứ 2 sẽ làm mất đi vết tích của exeption trước đó, nó cũng ko được lưu trữ vào stack trace, nơi mà các debug tool dựa vào để đưa lại thông tin ==> **Không có thông tin chính xác khi debug**

Khi mà close bằng tay nó như thế thì resource tự động close thì có phải đỡ hơn biết bao không?

II. Try-with-resources

Có lẽ đọc được nỗi lòng của nhiều anh DEV ngày đêm debug mà ko ra nguyên nhân thì chúa cũng đã update Java 7, ban cho Autocloseable interface.

Các classes, intefaces trong lib của Java hay bên thứ 3 có thể implement hoặc extend Autocloseable. Cùng viết lại 2 function trên thử nhá:

 static String firstLineOfFile (String path) thows IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readline(); } }
 static void copy(String src, String destination) throws IOException { try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(destination)){ int n; byte [] buf = new byte[BUFFER_SIZE]; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } }

Có thể nhìn qua ngay được là source đã gọn lại và dễ đọc hơn rất nhiều. Ngoài ra nó cũng giúp việc đoán bug tốt hơn.

Trường hợp này khi xẩy ra multi exception, thì exception sau luôn loại bỏ exception trước nó và báo exception của minh. Nhưng lần này không chỉ đơn thuần là loại bỏ, mà nó sẽ in vào trong stack trace rằng thằng trước đấy đã bị loại bỏ. Và để truy cập vào stack trace để xem thông tin thì chúa cũng đã cung cấp getSuppressed method để hỗ trợ cho mục đích muốn xử dụng.

Vì thế có thể thấy viết theo cách này ngoài mục đích không để thằng em nó chửi thì cũng giúp cho việc debug được đi vào đúng trọng tâm vấn đề hơn.

Bài này mục đích để lưu lại cho khỏi quên sau đi xem qua Effective java từ Trí.

Bình luận

Bài viết tương tự

- vừa được xem lúc

15 JAVA CODING BEST PRACTICES CHO NGƯỜI MỚI

Ngay từ đầu, Java là một trong những ngôn ngữ lập trình thống trị. Trong thời đại tiến bộ ngày này, nơi mà nhiều ngôn ngữ mạnh mẽ có mặt đã chết từ lâu, Java vẫn phù hợp và phát triển nhanh chóng theo

0 0 69

- vừa được xem lúc

Sử dụng Apache Kafka với Quarkus

Kafka là gì. Kafka là gì? – Đó là hệ thống message pub/sub phân tán (distributed messaging system).

0 0 41

- vừa được xem lúc

How to create first application on Spring MVC?

In order to create and develop a Spring MVC application, we need some prerequisite software and tools. We will setup Java, configure Maven build tool, install Tomcat web server, configure the Spring T

0 0 24

- vừa được xem lúc

Java Inner Class

Java Inner Classes (Nested Classes) là gì . . . .

0 0 24

- vừa được xem lúc

Series Quarkus - Tập 1: Quarkus là gì và cách khởi tạo

Các kiến trúc Java stacks truyền thống chẳng hạn như kiến trúc Monolithic. Ta thường viết tất cả các Authorization, presentation,business,.

0 0 21

- vừa được xem lúc

Thử tạo một Dependency Injection Framework đơn giản viết bằng Java

Hello forks. (Source code tham khảo trong bài nằm ở cuối bài viết). 1.Tạo các annotations.

0 0 24