考慮以下代碼:最好在進程之前進行驗證,或者只是引發異常?
x = Repo.GetX(13);
Services.Process(x);
我可以檢查x是處理之前空,我也可以有Services.Process()拋出一個異常,如果X是零和使用try/catch塊。
哪種方法更可取?
(或者我應該都做,只是在x變成空不知何故從其檢索點處理它的例外情況?)
考慮以下代碼:最好在進程之前進行驗證,或者只是引發異常?
x = Repo.GetX(13);
Services.Process(x);
我可以檢查x是處理之前空,我也可以有Services.Process()拋出一個異常,如果X是零和使用try/catch塊。
哪種方法更可取?
(或者我應該都做,只是在x變成空不知何故從其檢索點處理它的例外情況?)
如果你試圖決定之間:
x = Repo.GetX(13);
try {
Services.Process(x);
} catch (NullPointerException) {
System.err.println('x is NULL');
}
或
x = Repo.GetX(13);
if (x != NULL) {
Services.Process(x);
} else {
System.err.println('x is NULL');
}
然後意識到他們並不意味着同樣的事情。第一個捕獲任意由Process
引發的空指針異常。第二個僅處理x
本身爲NULL的情況 - 如果Process
確實爲x.foo().bar()
,並且x.foo()
返回NULL,則不處理它。
您應該根據您可以處理的錯誤來決定兩者之間的關係。
在Services.Process
在案,以拋出NullPointerException當且僅當x
是空的情況下,使(假設我們相信文檔)兩個都意味着同樣的事情,那麼我會做第二個。這樣,如果文檔處於謊言狀態,並且Services.Process
中存在一個導致其他情況的錯誤,那麼我們不會錯誤地處理/報告例外情況,就好像x
事實上不是NULL一樣。
所以,漁獲物和在兩種情況下抑制異常:
不要捕捉,只是因爲你知道一個情況可能導致的異常,就可以搞定,當相同的異常可能會被拋出其他原因。我想你可以這樣做:
x = Repo.GetX(13);
try {
Services.Process(x);
} catch (NullPointerException) {
if (x == NULL) {
System.err.println('x is NULL');
} else {
throw;
}
}
但在我看來,不必要的冗長在這種情況下:因爲我們可以提前檢查x
是否爲空,我們不妨。存在這樣的情況,不過,在那裏你趕上一個例外,因爲這是不可能的,或只是愚蠢的嘗試提前預測是否會發生與否:
String s = Rep.GetString(13);
try {
f = Float.parseFloat(s);
System.out.println('is a number');
} catch (NumberFormatException) {
System.out.println('not a number');
}
我們可能檢查s
是否是之前調用一個有效的數字parseFloat
,但基本上會做兩次相同的工作 - 檢查一個字符串是一個有效的float與實際轉換它幾乎相同。因此,理解這個例外是有道理的 - 我們知道它意味着什麼,我們知道該怎麼做,我們無法真實地阻止它發生。
(或者你可以使用DecimalFormat.parse,不扔在所有)
遠東更好地檢查。異常處理通常很昂貴。
像往常一樣,這種問題的正確答案是:這取決於。
如果可能,最好的方法是定義一個執行這種檢查的邊界。邊界內的所有東西都可以依賴於所有被很好地初始化的東西。如果還是空着的話,用NPE炸燬是非常合適的。
在嘗試執行實際工作之前,通常要檢查前提條件,以使代碼更簡潔。
如果你不能在你的系統中建立這些邊界,問題是:當x爲NULL並且沒有處理結果異常時會發生什麼,當你不處理它時你有什麼選擇?
在許多情況下,你無論如何都不能做太多的事情,然後讓異常進入調用堆棧直到ui(或者服務接口或其他)就可以了。
但是有時用空參數調用進程會摧毀一塊硬件,殺死一個病人或者以其他方式非常噁心。在這種情況下:請在潛在的有害行爲之前檢查。
應該使用異常處理來處理異常。
如果你的東西x不應該爲空使用try/catch語句。如果x將在某些情況下爲空使用和if語句。
只要這個代碼不會在一個巨大的循環中運行,性能不應該被考慮。如果它確實運行在一個緊密的循環中,那麼應該進行測試,並根據那些實現進行調整。 – 2011-05-16 11:06:48
當「特殊」情況很常見時,異常處理通常很昂貴*。如果發生數千次中的一次,跳過檢查並拋出異常實際上可能會更快。正如另一個答案所述,*取決於*。除了表演,還有其他一些事情需要擔心。 – cHao 2011-05-16 11:08:36