2012-02-29 52 views
7

Tôi muốn bắt một ngoại lệ, đăng nhập nó, đặt một lá cờ, và rethrow cùng một ngoại lệjava: không thể rethrow ngoại lệ: Unhandled loại trừ ngoại lệ

tôi có mã này:

public Boolean doJobWithResult() { 
    boolean result = true; 
    final Feed feed = Feed.findById(feedId); 
    try { 
     feed.fetchContents(); 
    } catch (Exception ex) { 
     result = false; 
     Logger.info("fetching feed(%d) failed", feedId); 
     throw ex; 
    } 
    return result; 
} 

Nhưng nhật thực vẫn phàn nàn tại lệnh ném cũ, nói rằng "Ngoại lệ loại trừ ngoại lệ" và đề xuất tôi thêm khối thử nghiệm xung quanh nó.

Trong thực tế, tôi muốn quá trình gọi phương pháp này để xử lý các ngoại lệ, và không xử lý nó bản thân mình ... Tôi chỉ muốn trở thành sự thật nếu mọi thứ diễn ra ok, và đăng nhập nó nếu có một ngoại lệ

On Mặt khác, tôi có thể bao gồm ngoại lệ bên trong một ngoại lệ khác, nhưng tôi không thể ném ngoại lệ tương tự.

bất kỳ ý tưởng nào?

Trả lời

2

Tôi nghĩ rằng có những điều khác nhau đề cập đến ở đây:

  1. Bạn có thể muốn doJobWithResult() để trở về đúng trên thành công và sai trên thất bại, hoặc trả lại gì trên thành công và ném một ngoại lệ trên thất bại. Cả hai cùng một lúc là không thể. Trong trường hợp đầu tiên, hãy nắm bắt Ngoại lệ, ghi lại và trả về false, trong trường hợp thứ hai, hãy thay đổi chữ ký của bạn để trả lại void và ném một ngoại lệ và xử lý nó trong người gọi.
  2. Đó là Không để bắt ngoại lệ, đăng nhập và thử lại. Tại sao? Bởi vì một người gọi tiềm năng của phương pháp của bạn không biết rằng bạn đã đăng nhập nó, và migh đăng nhập nó là tốt. Hoặc là ném một ngoại lệ (trong trường hợp đó người gọi phải đối phó với nó) hoặc nắm bắt và xử lý nó (đăng nhập nó).
  3. Lưu ý rằng việc ném Exception không cung cấp cho người gọi phương thức của bạn bất kỳ manh mối nào có thể xảy ra trong phương pháp của bạn, tốt hơn là ném ngoại lệ cụ thể hơn hoặc bọc ngoại lệ trong một trường hợp do người dùng xác định. .
  4. Hơn nữa, nếu bạn ném Exception, người gọi có thể bị bắt để bắt Exception mà không nhận thấy điều này cũng sẽ bắt mọi RuntimeException (kể từ khi xuất phát từ Exception), có thể không phải là hành vi mong muốn.
+0

tất cả các câu trả lời đều khá hữu ích, tôi nghĩ điều này cũng đưa ra một vài gợi ý về cách xử lý ngoại lệ ... – opensas

2

Kể từ Exceptionchecked, một sự thay thế để thu hút sự Exception là tuyên bố phương pháp của bạn như ném nó:

public Boolean doJobWithResult() throws Exception { 
    // ... 
} 
7

phương pháp doJobWithResult của bạn cần phải tuyên bố rằng nó có thể ném ngoại lệ:

public Boolean doJobWithResult() { 

trở thành

public Boolean doJobWithResult() throws Exception { 
3

Nếu doJobWithResult không phải xử lý ngoại lệ, sau đó loại bỏ khối catch và thêm "ném ngoại lệ" vào chữ ký phương thức. Việc ghi nhật ký ngoại lệ có thể được thực hiện trong lớp/phương thức phải đối phó với Ngoại lệ trong một khối try/catch tương ứng.

2

Không cần đặt kết quả là sai trong khối catch, vì giá trị sẽ không được trả lại (vì chúng tôi đang ném ngoại lệ).

Phương pháp của bạn cũng nên tuyên bố rằng nó ném ngoại lệ và do đó khách hàng sẽ bị buộc phải xử lý.

Đồng thời xem xét sử dụng ngoại lệ cụ thể hơn sẽ được đưa ra trong trường hợp cụ thể này.

4

Bạn có thể ném cùng một ngoại lệ nếu bạn thêm throws Exception vào chữ ký phương thức của mình. Nếu không, bạn có thể ném RuntimeException.

public Boolean doJobWithResult() { 
    boolean result = true; 
    final Feed feed = Feed.findById(feedId); 
    try { 
     feed.fetchContents(); 
    } catch (Exception ex) { 
     result = false; 
     Logger.info("fetching feed(%d) failed", feedId); 
     throw new RuntimeException(ex); 
    } 
    return result; 
} 

Trong một trường hợp như vậy, bạn sẽ không cần phải chỉ ra rằng public Boolean doJobWithResult() ném một cái gì đó nhưng chắc chắn rằng bạn xử lý nó đúng cách sau này (bắt hoặc hy vọng chủ đề của bạn để dừng lại ... đó là một RuntimeException afterall).

0

Bạn có thể ném một ngoại lệ được kiểm soát

Logger.info("fetching feed(%d) failed", feedId); 
throw new RuntimeException(ex); 
1

Thêm throws Exception phương pháp của bạn. Bạn cũng không cần thêm result = false; vào khối catch của mình.

1

Tôi nghĩ cách bạn xử lý ngoại lệ này thực sự thích hợp nếu không thể phục hồi bất kỳ lỗi nào của phương thức feed.fetchContents().(Ý tưởng tốt hơn là tạm dừng thay vì tiếp tục) Ngoài ra, tôi khuyên bạn nên sử dụng hệ thống phân cấp ngoại lệ cụ thể hơn.

Và một điều khác tôi nhận được từ sách java hiệu quả là nếu bạn viết một phương pháp như vậy bạn phải tài liệu với @throw (trong nhận xét) với lý do.

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