Java: Khối finally
Khối finally luôn luôn được thực thi khi khối try thoát. Điều này đảm bảo rằng khối finally được thực hiện ngay cả khi một ngoại lệ bất ngờ xảy ra. Nhưng finally hữu ích hơn nhiều so với việc chỉ xử lý ngoại lệ - nó cho phép lập trình viên tránh được việc mã dọn dẹp vô tình bị bỏ qua bởi một lệnh return, continue hoặc break. Việc đặt mã dọn dẹp vào khối finally luôn luôn là một việc làm tốt, ngay cả khi không có ngoại lệ nào được bắt.
try hoặc catch đang được thực hiện, thì khối finally không thể được thực thi. Tương tự như vậy, nếu thread thực hiện mã lệnh trong try hoặc catch bị gián đoạn thì khối finally có thể không thực hiện mặc dù toàn bộ ứng dụng vẫn đang tiếp tục thực hiện.
Khối try của phương thức writeList mà bạn đã làm việc dưới đây mở ra một PrintWriter. Chương trình phải đóng luồng (stream) trước khi thoát khỏi phương thức writeList. Điều này đặt ra một vấn đề hơi phức tạp vì khối try của writeList có thể thoát ra theo một trong ba cách sau:
- Câu lệnh
new FileWriterlỗi và ném raIOException. - Câu lệnh
list.get(i)lỗi và ném raIndexOutOfBoundsException. - Mọi việc đều thành công và khối
trythoát bình thường.
Hệ thống runtime luôn thực hiện các câu lệnh trong khối finally bất kể những gì xảy ra bên trong khối try. Vì vậy, nó là nơi hoàn hảo để thực hiện việc dọn dẹp.
Khối finally sau đây cho phép phương thức writeList dọn dẹp và sau đó đóng PrintWriter:
finally {
if (out != null) {
System.out.println("Đang đóng PrintWriter");
out.close();
} else {
System.out.println("PrintWriter không mở được");
}
}
Quan trọng: Khối finally là một công cụ quan trọng để ngăn ngừa sự rò rỉ tài nguyên. Khi đóng một tập tin hoặc thu hồi tài nguyên, ta đặt mã tương ứng trong khối finally để đảm bảo rằng tài nguyên luôn luôn được phục hồi.
Trong tình huống này ta cũng có thể xem xét việc sử dụng câu lệnh try-with-resources đối với việc thao tác với tài nguyên, câu lệnh này sẽ tự động giải phóng tài nguyên hệ thống khi không còn cần thiết.