2010-12-07 72 views
2

我有一個奇怪的問題,我一直在想,但永遠不會看到實際用途。我期待看看是否有足夠的理由。什麼時候處理空指針/引用異常首選做空檢查?

什麼時候處理空指針/引用異常首選做空檢查?如果有的話。

這適用於任何必須處理具有異常處理功能的空指針/引用的語言。

我對此的常見迴應是在執行任何指針/引用之前執行空檢查。如果非null,繼續像正常一樣使用它。如果爲null,則處理該錯誤或將其提升。

即(在C#)

string str = null; 
if (str == null) 
{ 
    // error! 
} 
else 
{ 
    // do stuff 
    int length = str.Length; 
    // ... 
} 

但是,如果我們不這樣做的檢查,只是一味地使用它,一個異常將提高。

string str = null; 
int length = str.Length; // oops, NullReferenceException 
// ... 

是一個例外,我們當然可以抓住它所以沒有從這樣阻止我們(或有):

string str = null; 
try 
{ 
    int length = str.Length; // oops, NullReferenceException 
    // ... 
} 
catch (NullReferenceException ex) 
{ 
    // but that's ok, we can handle it now 
} 

現在我承認,這不是最乾淨代碼,但它是不低於工作代碼,我通常不會這樣做。但是,有沒有設計模式或者這樣做有用?也許比直接做更有用,事先沒有檢查。

我能想象到的唯一情況可能是有用的是在一個多線程環境中,一個不受保護的共享變量被設置爲null太早。但是這種情況多久發生一次?保護變量的好代碼不會有這個問題。或者如果有人在編寫調試器,並希望顯式拋出異常,只是爲了包裝它或什麼。也許一個看不見的性能好處或消除代碼中其他事物的需要?

我可能已經回答了我的一些問題,但有沒有其他用途來做到這一點?我並不是在尋找,「這樣做只是因爲我們可以」這樣的例子,或者只是寫得不好的代碼,但是它的實際用途。雖然我會保持不變,「沒有實際用處,請檢查一下。」

+0

永遠不會捕獲一個`NullReferenceException`。這意味着你的代碼有些錯誤。 – leppie 2010-12-07 08:30:22

+1

我不確定每個人都明白我的問題的意圖,但是我會從中得出這樣的結論,它從來沒有真正有用,並且在使用它的地方沒有模式。我知道我們不應該在有更好的方法來處理這件事情時這樣做,我只是想知道是否有足夠的理由去做。但是伊格納西奧和豪伊的答案是一個足夠強烈的理由,爲什麼它沒有完成。 – 2010-12-09 01:51:58

+0

我完全不知道爲什麼這是-1。 upvoted,因爲這是一個有趣的問題,但答案可能是語言和平臺特定的。 – scriptocalypse 2011-04-27 23:27:17

回答

3

問題是所有空指針異常看起來都很相似。可以添加的任何會計信息指示哪個名稱觸發該異常不會比僅僅首先檢查null更高效。

1

如果您希望該值不爲空,那麼執行任何檢查都沒有意義。但是,例如,在接受參數時,測試您需要爲非空的參數並根據需要引發ArgumentNullExceptions是有意義的。

這是首選的原因有兩個:

  1. 通常,您將使用ArgumentNullException構造的一個字符串形式傳入參數名稱。這在調試過程中提供了非常有用的信息,因爲編碼人員知道哪個參數爲空。如果您的源不可用(或者如果異常跟蹤是由未安裝調試符號的最終用戶提交的),否則可能無法確定實際發生的事情。對於其他異常類型,您還可以指定哪個變量爲null,這可能是非常有用的信息。
  2. 捕獲null取消引用是CLR可以執行的最昂貴的操作之一,如果您的代碼拋出大量的NullReferenceExceptions,這可能會嚴重影響性能。測試無效並做一些其他事情(甚至拋出異常!)是一個更便宜的操作。 (類似的原理是,如果你聲明與醒目的NRE的明確意圖的catch塊,你做錯了什麼別的地方,你應該有解決它,而不是使用try/catch語句。追趕的NRE應該永遠是不可或缺的)任何算法的一部分。

話雖這麼說,不亂丟你的代碼的地方,你不要指望空值空測試。但是如果有可能引用變量爲空(例如,如果引用是由外部代碼提供的話),那麼你應該總是測試。

+0

這是一個處理空對象/指針的好(平衡)方法。從C++的角度來看,這篇文章給出了一個有趣的觀點來看待過多的空檢查。 [空指針檢查 - 它是軟件開發的靈丹妙藥](https://cognitivewaves.wordpress.com/2014/12/26/null-pointer-checks) – 2015-03-22 10:59:04

1

我已經超過10年的編程Java和我不記得一個單一的時間我已經明確地試圖抓住一個空指針異常。

有時候變量有時候會是空的(例如對象的可選屬性),在這種情況下,我需要測試null(obj.attr!= null),或者我希望變量不是任何時候都是null(在這種情況下,null表示代碼中其他地方的錯誤)。如果我正在編寫其參數(String s)爲空的方法(稱爲isUpperCase),那麼我顯式測試null,然後拋出IllegalArgumentException。

永遠做什麼,默默地從零恢復。如果一個方法應該返回一個字符串中大寫字符的數量並且傳遞的參數爲null,那麼我將永遠不會「隱藏」它,通過靜默地返回0來掩蓋潛在的錯誤。

0

Personnally(做C++),除非有向我保證,我的指針沒有nullptr強烈的合同,我一直對其進行測試,並返回錯誤,或者,如果這是允許不返回。

0

在Objective-C,你可以放心地做零,你可以用一個非空做和零最終被一個空操作,任何東西。事實證明,這非常方便。少了一些樣板空白檢查,並且例外情況是爲真正特殊情況保留的。或者這會被認爲是草率編碼?