Atitit避免出現空指針異常解決方案
1. Null的問題1
2. 強制區分一般引用vs 可空引用 vs 強制引用,或者說非空引用2
3. ?運算符(問號運算符) !感歎號運算符避免出現空指針異常,2
4. Java 8中的Optional類2
4.1.1. 為什麼使用Optional要比常見的null檢查強?3
5. 另一個救星! Objects.requireNonNull3
5.1.1. 為什麼比if(myObj!=null)要好?3
6. 參考4
含空引用的編程語言是一個價值十億美元的錯誤(譯者注:圖靈獎得主 Tony Hoare 說過)。但是為什麼呢?當然,他們可能會導致NullReferenceException,但那又怎樣?只要使用不當,一個語言的任何一個元素都可導致錯誤啊
換句話說,有兩種情況會出現判空語句:
· null返回值按找約定是正常的返回值
· null返回值不是正常的返回值
第二種情況很簡單。可以使用assert來判斷或者是允許程序報錯(即拋NullPointerException)。斷言是一個被充分利用的Java特性,在1.4版本中加入了這個特性。語法如下:
NullPointerException最主要的問題是沒有一個biz 說明。
帶有說明的異常要比光禿禿的拋出一個NullPointerException要好的多。
作者:: 綽號:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿爾 拉帕努伊 ) 漢字名:艾龍, EMAIL:[email protected]
轉載請注明來源: http://www.cnblogs.com/attilax/
的根源在於C#無法表達出非空引用的概念,這也導致讓編譯器強制進行空檢查變成一種過於繁重的任務。
為了應對這個問題,某條提議建議使用一種強制引用,以及一種明確的可空引用的定義。在提議中,可空引用將使用?後綴進行定義,正如可空值類型的定義方式一樣。而強制引用,或者說非空引用將使用!後綴進行定義。
強制引用以及可空引用都應該被視為一種僅限於語言本身的概念,它們只是改變了編譯器的行為,但不會改動所生成的IL代碼
在編譯器允許訪問可空引用對象的任何方法或屬性之前,必須明確地檢查空引用。並且在將某個可空引用轉型為強制引用之前,也必須對空引用進行檢查。
強制引用需要編譯器證實其中包含的值不可為空。由於這是一種僅限於編譯器的規則,因此無法保證在反序列化等場景中能夠同樣生效。
在閱讀這條提議的完整內容時,你會注意到其中提到的某個術語“一般引用”。它指的是C#中的普通引用,它既不是強制的,也不是明確定義為可空的。由於這種引用將被視為遺留代碼,因此可以通過AllowGeneralReferences這一屬性告訴編譯器不允許在代碼中使用一般引用。
在結合隱式變量定義時,可以在var關鍵字中使用!或?後綴。
簡單的方法就是檢查Optional包裝器是否真的有值(使用isPresent方法)——你會懷疑這和使用if(myObj != null)相比有什麼好處。別擔心,這個我會解釋清楚的
你可以使用orElse方法,這樣萬一封裝的確實是一個null值的話可以用它來返回一個默認值——它的好處顯而易見。在提取出真實值的時候可以避免調用ifPresent方法這樣明顯多余的方式了。
· 使用Optional最大的好處就是可以更明白地表述你的意圖——返回null值的話會讓消費者感到疑惑(當真的出現NPE的時候)這是不是故意返回的,因此還得查看javadoc來進一步定位。而使用Optional就相當明了了。
· 有了Optional你就可以徹底避免NPE了——如上所提,使用Optional.ofNullable,orElse以及orElseGet可以讓我們遠離NPE。
如果拋出NPE的話,我們怎麼能確定到底是哪個是null的?
Objects.requireNonNull(key, "Key is null");
requireNonNull方法
· 如果對象不為null的話就返回它本身
· 如果值為null的話,返回的NPE會帶有指定的消息
你所看到的棧跟蹤信息會很清楚地看見Objects.requireNonNull的方法調用。這個再配合你自己的錯誤日志,可以讓你更快地定位問題。。。至少在我看來是更快。
空指針的救星 - 博客 - 伯樂在線.htm
在Java中如何避免“!=null”式的判空語句? - ImportNew.htm
C#的未來:追蹤空引用.htm