[英]Java no-argument constructor: Throw impossible exception, or have empty catch block?
無參數構造函數拋出一個不可能的異常或者有一個空的catch塊是否更好? 假設我有一個這樣的課程。
public class Foo {
private int num;
private String numString;
public Foo() throws NumberFormatException {
setNum("1");
}
public void setNum(String s) throws NumberFormatException {
// In reality, complex code goes here
num = Integer.parseInt(s);
numString = s;
}
}
編譯器強制構造函數拋出NumberFormatException(這將永遠不會發生)或具有try / catch塊。 但是,有一個空的捕獲塊是否正確,這通常是不受歡迎的?
public Foo() {
try {
setNum("1");
}
catch (NumberFormatException e) { }
}
請注意,Foo將是一個庫類,其他人會使用它,因此使用無參數構造函數拋出一個不可能的異常會令人困惑。 另請注意,真正的異常是自定義異常,而不是NumberFormatException,這可能會使庫用戶更加困惑,他們可能覺得他們必須在不需要時閱讀自定義異常。
NumberFormatException
是一個RuntimeException
,因此您不需要在throws
子句中列出它 - 只是假裝它不在那里。 這適用於方法和構造函數。
RuntimeException
類(包括RuntimeException
本身)都是“未經檢查的異常”,這意味着編譯器不會強制您在try / catch子句中檢查它。 相比之下,任何不是RuntimeException
子類的Exception
都會被輕松調用,這是一個經過檢查的異常。
如果它是一個檢查過的異常(也就是說,不是RuntimeException
的子類),但是你確定你永遠不能觸發它,那么捕獲它是安全的。 而不是完全吞下它,最好將它包裹在一個未經檢查的異常中。
try {
thisCodeCanNeverThrowAnIOException();
}
catch (IOException e) {
throw new AssertionError(e); // juuust in case!
}
現在你的代碼編譯了,對於你從未期望拋出的異常沒有throws
子句,但是如果由於某些bug或將來的更改,異常最終會被拋出,則不會隱藏嚴重錯誤。
(注意那些閱讀注釋的人:我最初在代碼示例中throw new RuntimeException(e)
,但是Stephen C和Peter Lawrey指出,在Java 1.4.2和更新版本中,AssertionError更好)。
因為s必須是一個數字,為什么不通過setNum()而不是當前字符串傳遞一個整數? 始終可以對字符串解析整數。
我會說這取決於你的業務關懷或個人編碼風格,如果你選擇拋出一個異常它可能更好的擁有和包裝異常,如果你傳入的參數不正確或沒有意義,你可以拋出現在例外。
無論拋出NumberFormatException,這都是一個正確的決定,你可以抓住它。 它可能在您的庫類,調用者類或您不知道的地方。 沒有它,程序將會失效。
在您的情況下,您是否將無數字符串視為合法值,如果是,則您有責任將異常保留在包中。
我會說:從來沒有一個空的擋塊(無論如何)。 正如@yshavit指出的那樣,吞下可能的錯誤並不是一個好習慣。
正如@ stephen-c所說,使用斷言是向前邁進的一步,但這個解決方案有兩個缺點:
所以我的建議是@yshavit提案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.