簡體   English   中英

可以為被調用方法引發的異常聲明檢查異常嗎?

[英]Is it okay to declare a checked exception for an exception thrown by a called method?

考慮一下:

public void Do() throws Exception {

 if (blah) throw new Exception(...);

 Thingy thingy = ...;

 Foo(thingy);
}

public void Foo(Thingy thingy) throws EmptyThingyException {

   if (thingy == null || 
     thingy.isEmpty()) throw new EmptyThingyException();

  ...
}

public class EmptyThingyException extends Throwable { ... }

在這種情況下,是不是還好沒有處理EmptyThingyExceptionDo ,並宣布Do像這樣:

public void Do() throws Exception, EmptyThingyException {

還是我必須Do處理EmptyThingyException ,然后再次將其扔回,如下所示:

public void Do() throws Exception, EmptyThingyException {
    try {
    } catch (EmptyThingyException empty) {
      throw empty;
    }
    ...
  }

這個問題的簡短答案是:

是的,聲明由調用方法引發的檢查異常是正確的。

方法如何實現其目的是實現細節,它與接口直接執行多少操作或委派給方法多少無關緊要。 仔細定義了有關檢查異常的語言規則,以確保方法通告它們可能拋出的所有檢查異常或它們調用的方法(但不由方法本身處理)。 讓未處理的異常“拋出”方法就是應該如何工作。 的確,答案是在“非本地異常處理”構造的名義下,它被認為是在唯一真正的動作在某些情況下“不起作用”的情況下,從無窮無盡的錯誤處理中全力以赴,直至整個調用鏈。指向起點附近。

為了與該方法保持一致,您應該只catch將要處理的異常。 清理代碼應該finally實現,因此catch異常的正常原因是在某個時間記錄異常和/或放棄任務,而不是讓堆棧進一步松開。

在這種情況下,最好的答案是拋出IllegalArgumentException

throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");

毫無疑問,這是明智的。 正確的代碼不應遇到非法的參數,並且應該期望它們很少被拋出,並表明程序存在缺陷(無論是在類中,是程序包還是在用戶代碼中)。 外部和用戶輸入應直接驗證,並且程序不應依賴IllegalArgumentException

在實踐中, IllegalArgumentExceptionIllegalStateException應該覆蓋“內部錯誤”,分別表示“您不能使用此錯誤”或“您現在不能這樣做”,並應添加注釋以指定錯誤。

您可能將這兩個子類划分為子類,因為消費者代碼可能會對不同的非法行為做出不同的反應,這使純屬簡單。

程序的正確性包括程序從不對程序的其他部分進行非法調用或進入無效或損壞的狀態,並且異常僅是由於環境故障而發生,這意味着無法完成程序或程序中的子任務。意。

如果您想在異常發生后做某事 ,請使用try-catch ,也可以在方法上聲明它。

除此之外,如果EmptyThingyException子類Exception ,那么它是沒有必要宣布EmptyThingyException當你聲明Exception

1-聲明您的方法可以拋出的特定檢查異常

public void foo() throws Exception { //Incorrect way
}

始終避免像上面的代碼示例中那樣進行操作。 它根本無法達到檢查異常的全部目的。 聲明您的方法可以拋出的特定已檢查異常。 如果此類檢查的異常太多,則可能應將它們包裝在您自己的異常中,並在異常消息中添加信息。 如果可能,您還可以考慮代碼重構。

2-始終僅捕獲您可以實際處理的那些異常

catch (NoSuchMethodException e) {
   throw e; //Avoid this as it doesn't help anything
}

好吧,這是最重要的概念。 不要僅僅為了捕獲異常就捕獲任何異常。 僅在您要處理任何異常或要在該異常中提供其他上下文信息時才捕獲任何異常。 如果您不能在catch塊中處理它,那么最好的建議就是不要僅將其重新拋出就捕獲它。

3-避免使用Throwable類

就我所知,Throwable是Exception和Error的超類,據我所知,當您想同時處理異常和錯誤時,需要使用Throwable,但這絕對不是您關心的問題,大多數Java代碼都處理Exception,這就是方法在需要處理已檢查的異常時可以使用http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html

**好吧,如果我是你,我會做類似的事情:

public void Do() throws BlahIsFoundException{
 try {
     if (blah) throw new BlahIsFoundException(...);

     Thingy thingy = ...;

     Foo(thingy);
 } catch(EmptyThingyException exception) {
     //Handle the exception correctly, at least log it
 } finally {
     //Do some clean up if needed, for example close a database connection or free some resources.
 }
}

public void Foo(Thingy thingy) throws EmptyThingyException {

   if (thingy == null || 
     thingy.isEmpty()) throw new EmptyThingyException();

  ...
}

public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }

希望對您有所幫助,這里有一些不錯的文檔可供閱讀: http : //docs.oracle.com/javase/tutorial/essential/exceptions/index.html http://howtodoinjava.com/best-practices/java-exception-handling -最佳實踐

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM