Tôi đang xem xét một số mã mới. Chương trình có một thử và một khối cuối cùng chỉ. Vì khối catch bị loại trừ, khối try làm việc như thế nào nếu nó gặp một ngoại lệ hoặc bất cứ thứ gì có thể ném được? Liệu nó chỉ đi trực tiếp đến khối cuối cùng?Java Thử Catch Cuối cùng các khối không có Catch
Trả lời
Nếu bất kỳ mã nào trong khối thử có thể ném ngoại lệ đã kiểm tra, 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 soát được ném, nó sẽ bị loại ra khỏi phương thức.
Khối cuối cùng luôn được thực hiện, cho dù có ngoại lệ hay không.
Đoạn đầu tiên không nhất thiết phải đúng. Thử các khối có thể được lồng vào nhau. Bất kỳ ngoại lệ không bị bắt, không được kiểm soát hay không, sẽ bong bóng ra khỏi phương pháp. –
Thử các khối có thể được lồng nhau, nhưng tôi sẽ không khuyên bạn nên. Tôi không viết mã theo cách đó. – duffymo
@duffymo: Ý nghĩa của "bị bong ra khỏi phương pháp" là gì? – todayILearned
Bạn không thử với chương trình đó? Nó sẽ goto cuối cùng chặn và thực hiện khối cuối cùng, nhưng, ngoại lệ sẽ không được xử lý. Nhưng, ngoại lệ đó có thể bị overruled trong khối cuối cùng!
thế nào công việc khối try nếu nó gặp một ngoại lệ hoặc bất cứ điều gì Throwable
Trường hợp ngoại lệ được ném ra khỏi khối, cũng giống như trong bất kỳ trường hợp khác, nơi nó không bị bắt.
Khối cuối cùng được thực hiện bất kể khối thử được thoát ra như thế nào - bất kể có bắt giữ gì hay không, bất kể có bắt khớp hay không.
Khối bắt và cuối cùng là các phần trực giao của khối thử. Bạn có thể có một hoặc cả hai. Với Java 7, bạn sẽ có thể không có!
Khối cuối cùng luôn chạy sau khi khối thử kết thúc, cho dù thử kết thúc bình thường hoặc bất thường do ngoại lệ, er, có thể ném.
Nếu ngoại lệ được ném bởi bất kỳ mã nào trong khối thử, thì phương thức hiện tại chỉ đơn giản là ném lại (hoặc tiếp tục ném) cùng một ngoại lệ (sau khi chạy khối cuối cùng).
Nếu khối cuối cùng ném một ngoại lệ/lỗi/throwable, và đã có một ném đang chờ xử lý, nó trở nên xấu xí. Hoàn toàn thẳng thắn, tôi quên chính xác những gì xảy ra (rất nhiều cho chứng nhận của tôi năm trước). Tôi nghĩ rằng cả hai vật ném được liên kết với nhau, nhưng có một số voodoo đặc biệt bạn phải làm (tức là - một cuộc gọi phương pháp tôi sẽ phải tra cứu) để có được vấn đề ban đầu trước khi "cuối cùng" bị chặn, er, ném lên.
Ngẫu nhiên, thử/cuối cùng là một điều khá phổ biến để làm cho quản lý tài nguyên, vì java không có destructors.
Ví dụ: -
r = new LeakyThing();
try { useResource(r); }
finally { r.release(); } // close, destroy, etc
"Cuối cùng", thêm một tip: nếu bạn làm bận tâm để đưa vào một nắm bắt, hoặc là bắt cụ thể (dự kiến) lớp con Throwable, hoặc cập nhật tình "Throwable", không "ngoại lệ" , cho một bẫy lỗi tổng quát.Quá nhiều vấn đề, chẳng hạn như goofs phản ánh, ném "Lỗi", chứ không phải là "ngoại lệ", và những người sẽ trượt ngay bởi bất kỳ "bắt bài" được mã hóa như:
catch (Exception e) ... // doesn't really catch *all*, eh?
làm điều này thay vì:
catch (Throwable t) ...
Xem câu trả lời của Carlos Heuberger bên dưới cho phần xấu xí. –
Khối cuối cùng được thực hiện sau khi khối thử hoàn thành. Nếu một cái gì đó được ném bên trong khối thử khi nó rời khỏi khối cuối cùng được thực thi.
Một lưu ý nhỏ trên try
/finally
: Các cuối cùng sẽ luôn thực hiện trừ khi
System.exit()
được gọi.- JVM gặp sự cố.
- Khối
try{}
không bao giờ kết thúc (ví dụ: vòng lặp vô tận).
Điều gì về 'try {..} catch {throw ..} cuối cùng {..}'? Tôi nghĩ cuối cùng sẽ không được thực hiện – sbeliakov
Trong trường hợp đó cuối cùng vẫn sẽ được gọi. Chỉ có ngoại lệ ban đầu bị mất. –
Cuối cùng cũng sẽ không được thực hiện nếu bạn gọi System.exit() trước đó. –
Java Language Specification (1) mô tả cách try-catch-finally
được thực thi. Không có điểm bắt nào tương đương với việc không có khả năng bắt được Ném được.
- Nếu thực hiện các khối try hoàn đột ngột vì một ném của một giá trị V, sau đó là một sự lựa chọn:
- Nếu kiểu thời gian chạy của V là gán cho tham số của bất kỳ mệnh đề catch của câu lệnh try, sau đó ...
...- Nếu kiểu thời gian chạy của V là không thể chuyển nhượng cho các tham số của bất kỳ mệnh đề catch của câu lệnh try, sau đó khối cuối cùng được thực hiện. Sau đó, có một sự lựa chọn:
- Nếu khối cuối cùng hoàn thành bình thường, sau đó báo cáo kết quả thử hoàn đột ngột vì một ném của V. giá trị
- Nếu khối cuối cùng hoàn thành đột ngột vì lý do S, sau đó báo cáo kết quả thử hoàn thành đột ngột vì lý do S (và vứt bỏ giá trị V bị loại bỏ và bị lãng quên).
Các bên cuối cùng đã được thực hiện trước khi ném ngoại lệ đối với khối ngoài.
public class TryCatchFinally {
public static void main(String[] args) throws Exception {
try{
System.out.println('A');
try{
System.out.println('B');
throw new Exception("threw exception in B");
}
finally
{
System.out.println('X');
}
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
}
catch(Exception e)
{
System.out.println('Y');
}
finally
{
System.out.println('Z');
}
}
}
Kết quả trong
A
B
X
Y
Z
phiên bản Java trước khi phiên bản 7 cho phép ba kết hợp của try-catch-cuối cùng ...
try - catch
try - catch - finally
try - finally
finally
khối sẽ được luôn luôn thực hiện không có vấn đề gì đang xảy ra trong try
hoặc/và catch
khối. vì vậy nếu không có khối catch
, ngoại lệ sẽ không được xử lý tại đây.
Tuy nhiên, bạn vẫn sẽ cần một trình xử lý ngoại lệ ở đâu đó trong mã của mình - trừ khi bạn muốn ứng dụng của mình gặp sự cố hoàn toàn. Nó phụ thuộc vào kiến trúc của ứng dụng của bạn chính xác nơi mà trình xử lý đó.
- Khối thử Java phải được theo sau bằng cách bắt hoặc chặn cuối cùng.
- Đối với mỗi khối thử, có thể có không hoặc nhiều khối bắt, nhưng chỉ một khối cuối cùng bị chặn.
- Khối cuối cùng sẽ không được thực hiện nếu thoát chương trình (bằng cách gọi System.exit() hoặc bằng cách gây ra lỗi nghiêm trọng làm cho quá trình hủy bỏ).
"trước phiên bản 7 cho phép" bạn ngụ ý rằng Java 7 và Java 8 không cho phép ba kết hợp này? Tôi nghi ngờ đó là những gì bạn có ý nghĩa, nhưng đó là những gì câu trả lời của bạn ngụ ý. – Aaron
là khối cuối cùng được thực thi nếu có câu lệnh trả về trong khối thử? – Rahul
@Rahul Có, cuối cùng sẽ được gọi. Tham khảo: http://stackoverflow.com/questions/65035/does-finally-always-execute-in-java – roottraveller
thể trùng lặp của [Sự khác nhau giữa đánh bắt thử-thử-cuối cùng và] (http://stackoverflow.com/questions/2854910/difference-between-try-finally-and-try-catch) –
@ mP Mọi người nên thực hiện đánh giá mã và đặt câu hỏi từ họ là cách tìm hiểu và cải thiện. –