Tôi đang xem xét một số mã mới. Chương trình có một thử và cuối cùng chỉ chặn. Vì khối bắt được loại trừ, khối thử hoạt động như thế nào nếu nó gặp ngoại lệ hoặc bất cứ thứ gì có thể ném được? Nó chỉ đi trực tiếp đến khối cuối cùng?
Tôi đang xem xét một số mã mới. Chương trình có một thử và cuối cùng chỉ chặn. Vì khối bắt được loại trừ, khối thử hoạt động như thế nào nếu nó gặp ngoại lệ hoặc bất cứ thứ gì có thể ném được? Nó chỉ đi trực tiếp đến khối cuối cùng?
Câu trả lời:
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.
Một lưu ý nhỏ trên try
/ finally
: Cuối cùng sẽ luôn luôn thực thi trừ khi
System.exit()
được gọi là.try{}
khối không bao giờ kết thúc (ví dụ như vô tận vòng lặp).try{..} catch{ throw ..} finally{..}
? Tôi nghĩ cuối cùng sẽ không bị xử tử
Đặc tả ngôn ngữ Java (1) mô tả cách try-catch-finally
thực thi. Không bắt được tương đương với việc không bắt được có thể bắt được Ném được.
- Nếu việc thực thi khối thử hoàn thành đột ngột vì ném giá trị V, thì có một lựa chọn:
- Nếu loại thời gian chạy của V có thể gán cho tham số của bất kỳ mệnh đề bắt nào của câu lệnh thử, thì
...- Nếu loại thời gian chạy của V không thể gán cho tham số của bất kỳ mệnh đề bắt nào của câu lệnh thử, thì khối cuối cùng được thực thi . 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, thì câu lệnh thử hoàn thành đột ngột vì ném giá trị V.
- Nếu khối cuối cùng hoàn thành đột ngột vì lý do S, thì câu lệnh thử hoàn thành đột ngột vì lý do S (và việc ném giá trị V bị loại bỏ và bị lãng quên).
Phần bên trong cuối cùng được thực thi trước khi ném ngoại lệ vào khối bên 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
Khối cuối cùng luôn được chạy sau khi khối thử kết thúc, cho dù thử kết thúc bình thường hay bất thường do ngoại lệ, er, có thể ném được.
Nếu một 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ỉ cần 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 ra một ngoại lệ / lỗi / có thể ném được, và đã có một lần ném đang chờ xử lý, nó sẽ trở nên xấu xí. Thẳng thắn mà nói, 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 nhiều năm trước). Tôi nghĩ cả hai ném đều được liên kết với nhau, nhưng có một số voodoo đặc biệt bạn phải làm (nghĩa là - một cuộc gọi phương thức tôi sẽ phải tìm kiếm) để 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 để quản lý tài nguyên, vì java không có hàm hủy.
Ví dụ -
r = new LeakyThing();
try { useResource( r); }
finally { r.release(); } // close, destroy, etc
"Cuối cùng", một tip hơn: 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 chỉ bắt "Throwable", không "ngoại lệ", cho một nhận tất cả bẫy lỗi chung. Quá nhiều vấn đề, chẳng hạn như sự phản xạ, ném "Lỗi", thay vì "Ngoại lệ" và những vấn đề đó sẽ xảy ra ngay lập tức bởi bất kỳ "bắt tất cả" nào được mã hóa như sau:
catch ( Exception e) ... // doesn't really catch *all*, eh?
làm điều này thay vào đó:
catch ( Throwable t) ...
Các phiên bản Java trước phiên bản 7 cho phép ba kết hợp thử-bắt-cuối ...
try - catch
try - catch - finally
try - finally
finally
khối sẽ luôn được thực thi bất kể điều gì đang xảy ra trong khối try
/ và catch
. vì vậy nếu không có catch
khối, ngoại lệ sẽ không được xử lý ở đâ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 bạn - trừ khi bạn muốn ứng dụng của mình bị sập 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 xử lý đó.
- Khối thử Java phải được theo sau bởi khối bắt hoặc cuối cùng.
- Đối với mỗi khối thử có thể có 0 hoặc nhiều khối bắt, nhưng chỉ có một khối cuối cùng.
- Khối cuối cùng sẽ không được thực thi nếu chương trình thoát (bằng cách gọi System.exit () hoặc bằng cách gây ra lỗi nghiêm trọng khiến quá trình hủy bỏ).
khối thử hoạt động như thế nào nếu nó gặp ngoại lệ hoặc bất cứ thứ gì có thể ném được
Ngoại lệ được ném ra khỏi khối, giống như trong mọi trường hợp khác mà nó không bị bắt.
Khối cuối cùng được thực thi bất kể khối thoát được thoát ra như thế nào - bất kể có bắt được gì hay không, bất kể có bắt được khớp hay không.
Các 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ẽ không thể có!
Bạn không thử nó với chương trình đó à? Cuối cùng, nó sẽ 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ể được ghi đè trong khối cuối cùng!
Bên trong try
khối chúng tôi viết mã có thể ném một ngoại lệ. Các catch
khối là nơi chúng ta xử lý các ngoại lệ. Cácfinally
khối luôn thực hiện bất kể ngoại lệ xảy ra hay không.
Bây giờ nếu chúng ta có khối thử cuối cùng thay vì khối thử-bắt-cuối thì ngoại lệ sẽ không được xử lý và sau khối thử thay vì điều khiển sẽ bắt khối thì cuối cùng sẽ chặn. Chúng ta có thể sử dụng khối thử cuối cùng khi chúng ta không muốn làm gì với ngoại lệ.