Câu trả lời:
Điều này rất hữu ích nếu bạn muốn phương thức hiện đang thực thi vẫn ném ngoại lệ trong khi cho phép các tài nguyên được dọn sạch một cách thích hợp. Dưới đây là một ví dụ cụ thể về xử lý ngoại lệ từ phương thức gọi.
public void yourOtherMethod() {
try {
yourMethod();
} catch (YourException ex) {
// handle exception
}
}
public void yourMethod() throws YourException {
try {
db.store(mydata);
} finally {
db.cleanup();
}
}
catch
khối, ngoại lệ được ném vào finally
sẽ được thực thi trước bất kỳ ngoại lệ nào trong try
khối. Vì vậy, nếu có hai ngoại lệ một try
và một trong finally
ngoại lệ duy nhất sẽ được ném là một ngoại lệ finally
. Hành vi này không giống nhau trong PHP và Python vì cả hai ngoại lệ sẽ được đưa ra cùng một lúc trong các ngôn ngữ này và thứ tự ngoại lệ try
trước tiên là sau đó finally
.
Đó là bởi vì lập trình viên muốn đảm bảo rằng nó db.cleanup()
được gọi ngay cả khi mã bên trong khối thử ném một ngoại lệ. Bất kỳ trường hợp ngoại lệ nào sẽ không được xử lý bởi khối đó, nhưng chúng sẽ chỉ được truyền lên trên sau khi khối cuối cùng được thực thi.
try
là ở đó để cho phép finally
. Ngoại lệ không được bắt.
Tại sao mã này làm theo cách này?
Bởi vì rõ ràng mã không biết cách xử lý các ngoại lệ ở cấp độ này. Điều đó tốt - miễn là một trong những người gọi thực hiện, tức là miễn là ngoại lệ cuối cùng được xử lý ở đâu đó.
Thông thường, mã cấp thấp không thể phản ứng thích hợp với các ngoại lệ vì người dùng cần được thông báo hoặc ngoại lệ phải được ghi lại hoặc phải thử một chiến lược khác. Mã cấp thấp thực hiện một chức năng và không biết về việc ra quyết định cấp cao hơn.
Nhưng mã vẫn cần phải dọn sạch các tài nguyên của nó (vì nếu không, chúng sẽ bị rò rỉ), do đó, nó chỉ thực hiện điều đó trong finally
điều khoản, đảm bảo rằng nó luôn xảy ra, cho dù có ngoại lệ được ném hay không.
Khối cuối cùng đảm bảo rằng ngay cả khi ném RuntimeException (có thể do một số lỗi trong mã được gọi), db.cleanup()
cuộc gọi sẽ được thực hiện.
Điều này cũng thường được sử dụng để ngăn chặn quá nhiều lồng:
try
{
if (foo) return false;
//bla ...
return true;
}
finally
{
//clean up
}
Đặc biệt là khi có nhiều điểm mà phương thức trả về, điều này cải thiện khả năng đọc vì bất kỳ ai cũng có thể thấy mã dọn dẹp được gọi trong mọi trường hợp.
Mã đang làm điều đó để đảm bảo rằng cơ sở dữ liệu được đóng lại.
Thông thường, cách bạn sẽ làm là đặt tất cả mã truy cập cơ sở dữ liệu của bạn vào khối thử, sau đó thực hiện cuộc gọi để đóng cơ sở dữ liệu trong khối cuối cùng.
Cách thử ... cuối cùng cũng hoạt động, có nghĩa là mã trong khối thử được chạy và mã trong khối cuối cùng được chạy khi kết thúc ... không có vấn đề gì.
Ngắn máy tính bị kéo mạnh ra khỏi tường, cuối cùng sẽ thực thi.
Điều này có nghĩa là ngay cả khi một ngoại lệ được gọi và phương thức phải mất ba năm để thực thi, nó vẫn sẽ đi vào khối cuối cùng và cơ sở dữ liệu sẽ bị đóng.
Nếu bất kỳ mã nào trong khối thử có thể đưa ra một ngoại lệ được kiểm tra, thì nó phải xuất hiện trong mệnh đề ném của chữ ký phương thức. Nếu một ngoại lệ không được kiểm tra được ném ra, nó sẽ bị bong ra khỏi phương thức.
Khối cuối cùng luôn được thực thi, cho dù có ngoại lệ được ném hay không.
fopen
hoặc kết nối DB (cũng trong PHP)