2009-10-02 31 views
5

Điều gì theo bạn cách đơn giản nhất để chặn tất cả các ngoại lệ trong một ứng dụng Java? Cần AOP để cung cấp loại chức năng này hoặc nó có thể được thực hiện với proxy động hay có cách nào khác không? Giải pháp đơn giản nhất cũng là một giải pháp tốt về tác động đến hiệu suất thực hiện? Tôi muốn nghe các giải pháp khả thi từ các nhà phát triển có kinh nghiệm hơn khi tôi đang cố gắng nắm bắt bí quyết kỹ thuật về chủ đề này.Làm cách nào để bạn chặn tất cả Ngoại lệ?

EDIT:

Cám ơn những lời khuyên tốt đã có, nhưng không theo lời khuyên hiện tại chỉ áp dụng cho trường hợp ngoại lệ kiểm tra? Điều gì về ngoại lệ không được kiểm soát, như NullPointerExceptions, nó sẽ không hữu ích nếu chúng có thể bị bắt và rằng ứng dụng bắt chúng đổ đống/ngăn xếp để cung cấp cho bạn bối cảnh hiện tại của ứng dụng tại thời điểm bị lỗi?

+0

bạn muốn làm gì với họ? –

+3

Bạn có muốn bắt tất cả Ngoại lệ * mỗi lần * không? Làm thế thì được ích gì? Làm thế nào bạn biết để xử lý bất kỳ của những người? –

+0

giả sử bạn sẽ viết một số loại trình quản lý có hành động cụ thể theo loại ngoại lệ. Hoặc cái gì đó đổ đống và đống để có được bối cảnh hiện tại của ứng dụng. Thành thật mà nói, tôi không thực sự làm bất cứ điều gì với nó, tôi chỉ cố gắng nắm bắt cách tiếp cận tốt nhất trong một kịch bản như vậy. – nkr1pt

Trả lời

5

Tại Nate và Konamiman ... Những gì bạn đang đề xuất không hoạt động và không trả lời câu hỏi của OP.

Điều gì xảy ra nếu OP bắt đầu một chuỗi mới từ bên trong try/catch của bạn?

Ví dụ:

public static void main(String[] args) { 
    try { 
     final Thread t = new Thread(new Runnable() { 
      public void run() { 
       System.out.println(3/Math.min(0,4)); 
      } 
     }); 
     t.start(); 
    catch(Throwable t) { 
     ... 
    } 
} 

Sau đó, bạn không bắt ngoại lệ.

Cách chính xác để làm điều đó là sử dụng Thread.setDefaultUncaughtExceptionHandler.

+0

có - quên điều đó. – Nate

+0

Như tôi đã nói tôi không biết nhiều về Java (vì vậy có lẽ tôi không nên trả lời, sau đó). Dù sao thì cũng tốt khi học cái gì đó mới mẻ. – Konamiman

+0

(Vì đây không phải là diễn đàn, xin lưu ý rằng câu trả lời có thể không được hiển thị theo thứ tự mà chúng được đăng.) – Arjan

3
public static void main(String[] args) { 
    try { 
     ... 
    catch(Throwable t) { 
     ... 
    } 
} 
+3

Giải pháp của Taylor L thực sự tốt hơn nếu bạn đang sử dụng Java 5+ - điều này không thể bắt ngoại lệ bên ngoài luồng chính. – Nate

+0

Tôi đồng ý với Nate. :-) –

+0

Điều gì sẽ xảy ra nếu một ngoại lệ xảy ra trong một chuỗi khác? –

11

Mục đích của bạn là muốn chặn mọi ngoại lệ - để ghi nhật ký, báo cáo lỗi là gì?

Ngăn chặn mọi ngoại lệ duy nhất trong mỗi dòng của một chương trình Java là có thể, nhưng có lẽ sẽ phải chịu một cú đánh hiệu suất khá. Nếu không thể tránh khỏi, có lẽ tốt nhất nên sử dụng một cái gì đó như AspectJ, có thể chạy lúc biên dịch (nghĩa là "dệt" vào tệp lớp của bạn) và nhanh hơn nhiều so với proxy động.

Nhưng đó là điều tôi sẽ cố gắng tránh làm bằng mọi giá! Nói chung tôi sẽ nói tốt hơn là giới hạn phạm vi của các ngoại lệ mà bạn muốn nắm bắt. Ngoài ra, bạn có thể muốn xem xét Thread.setDefaultUncaughtExceptionHandler, mà tôi thấy hữu ích khi hiển thị hộp thoại báo lỗi trong các ứng dụng GUI.

0

Quan trọng hơn so với chỉ đơn giản là bắt tất cả các trường hợp ngoại lệ là nơi bạn bắt ngoại lệ:

  1. Đừng bắt một ngoại lệ, trừ khi bạn có thể làm điều gì đó về nó. Nếu bạn không thể làm bất cứ điều gì về nó, hoặc là để cho nó bong bóng lên đến cấp độ tiếp theo hoặc bắt nó, re-wrap nó như là một ngoại lệ cụ thể hơn và lại ném nó.

  2. Luôn có khối xử lý ngoại lệ toàn cục (như trong câu trả lời của Nate) để bắt bất kỳ lỗi nào bạn không thể xử lý ở bất cứ nơi nào để bạn có thể thất bại một cách duyên dáng.

0

Nếu bạn chỉ muốn bắt Ngoại lệ, khối thử/nắm bắt sẽ đủ. Nếu bạn muốn ngăn chặn chúng được ném hoặc làm một số đăng nhập hoặc gói ngoại lệ, bạn có thể sẽ cần một số AOP để làm điều này. AspectJ sẽ xử lý nó khá tốt, nhưng hãy cẩn thận về các tắc nghẽn hiệu suất tiềm năng.

Proxy động sẽ chỉ hoạt động khi phương pháp được ủy quyền, vì vậy nếu bất kỳ Ngoại lệ nào được ném và bị bắt trong thực thi đối tượng proxy, không có phương tiện nào để chặn ngoại lệ.

Một điều cần xem xét là nếu bạn đang bắt tất cả ngoại lệ hoặc chỉ kiểm tra ngoại lệ. Để bắt tất cả ngoại lệ, lời khuyên around throwing hoặc after throwing của AspectJ sẽ xử lý một số phương pháp xung quanh mọi phương pháp, điều này liên quan đến việc tạo các đối tượng JoinPoint và các phương thức tổng hợp ở mọi lời gọi phương thức. Đây không phải là một vấn đề bình thường, trừ khi quá trình này ở trong một vòng eo hẹp, nơi mà bộ sưu tập rác có thể đi qua mái nhà.

9

Tương tự như câu trả lời của Phil, dưới đây là một số mã mẫu cho thấy cách sử dụng trình xử lý ngoại lệ chưa được nắm bắt. Điều này làm việc cho cả hai trường hợp ngoại lệ được kiểm tra và bỏ chọn.

Chỉnh sửa: Cập nhật để in dấu vết ngăn xếp dựa trên các nhận xét được cập nhật trong câu hỏi.

import java.lang.Thread.UncaughtExceptionHandler; 

public class Test { 

    public static void main(String[] args) throws Exception { 
     Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 

      @Override 
      public void uncaughtException(Thread t, Throwable e) { 
       e.printStackTrace(); 
      }} 

     ); 

     // throw new RuntimeException(); /* this works too */ 
     throw new Exception(); 
    } 

} 
0

Để tất cả những questionning sự cần thiết phải nắm bắt tất cả các trường hợp ngoại lệ ...

Có rất nhiều lý do hợp lệ để đón tất cả trường hợp ngoại lệ:

  • ai mentionned hiển thị một hộp thoại trong một ứng dụng GUI kể về sự cố
  • làm việc xung quanh lỗi trong API của bên thứ ba mà bạn thực sự cần
  • làm việc xung quanh lỗi trong một số triển khai JVM
  • phần mềm tự phục hồi.
  • báo cáo ngoại lệ trực tuyến tự động.

Lưu ý rằng Java chính nó chặn tất cả ngoại lệ trên EDT (Chủ đề công văn sự kiện) và sinh ra một EDT mới khi EDT chết. Bạn có thể xem xét rằng một hình thức "tự chữa bệnh" phần mềm. EDT chết không phải là một cái gì đó không nghe và không chính xác ngăn chặn các ứng dụng chạy đúng (ngược lại). (và, yup, Swing và AWT có một số lỗi, chỉ cần nhìn vào cuộc diễu hành của Sun bug;)

Có thể lập luận rằng bất kỳ phần mềm tự tôn trọng nào cũng phải tính đến trường hợp ngoại lệ không lường trước được (là tất cả các phần mềm bạn gửi 100% lỗi miễn phí và không bao giờ nhận được bản phát hành mới, sửa lỗi phát hành?) và làm điều gì đó thông minh khi ngoại lệ không lường trước được xảy ra.

Các 'một cái gì đó thông minh' có thể được ngăn chặn phần mềm từ đâm (như trong trường hợp EDT), cảnh báo người sử dụng, gửi một báo cáo vv

Đáp questionning cần phải làm một điều như vậy hoặc gợi ý rằng làm như vậy là một thực hành xấu nên IMHO được modded xuống.

Các vấn đề liên quan