由@NotNull 注解引出的關(guān)于Java空指針的控制(轉(zhuǎn))

由@NotNull 注解引出的關(guān)于Java空指針的控制(轉(zhuǎn))

Java 小技巧和在java應(yīng)用避免NullPonintException的最佳方法
在java應(yīng)用程序中赖条,一個(gè)NullPonintException(空指針異常)是最好解決(問(wèn)題)的方法。同時(shí)贴硫,空指針也是寫健壯的順暢運(yùn)行的代碼的關(guān)鍵简逮∮塘猓“預(yù)防好過(guò)治療”這句話也同樣適用于令人不爽的NullPonintException绕辖。通過(guò)應(yīng)用防御性的編碼技術(shù)和在遵守多個(gè)部分之間的約定胖腾,你可以再很大程度上避免NullPointException霍比。下面的這些java小技巧可以最小化像幕袱!=null這種檢查的代碼。作為經(jīng)驗(yàn)豐富的java程序猿悠瞬,你可能意識(shí)到這些技術(shù)的某部分項(xiàng)目當(dāng)中使用它们豌。但是對(duì)于大學(xué)一年級(jí)學(xué)生和中級(jí)開發(fā)者,這是一個(gè)很好的學(xué)習(xí)機(jī)會(huì)浅妆。

這是一些很容易學(xué)會(huì)的簡(jiǎn)單技術(shù)望迎,但是對(duì)于代碼質(zhì)量和健壯性來(lái)說(shuō)確實(shí)很重要。以我的經(jīng)驗(yàn)凌外,僅是第一個(gè)小技巧就已經(jīng)對(duì)改進(jìn)代碼質(zhì)量具有很大的作用了辩尊。

1)在已經(jīng)的String(字符串)調(diào)用 equal()和 equalsingnoreCase()而不是未知的對(duì)象
通常在已經(jīng)的非空字符串在調(diào)用equals()。因?yàn)閑qual()方法是對(duì)稱的康辑,調(diào)用a.equal()是同等于調(diào)用b.equal()摄欲,和這就是為什么很多部注意對(duì)象a和b轿亮,如果空的一邊被調(diào)用會(huì)到導(dǎo)致空指針。

Object unknownObject = null;//wrong way - may cause NullPointerExceptionif(unknownObject.equals("knownObject")){ System.err.println("This may result in NullPointerException if unknownObject is null");}//right way - avoid NullPointerException even if unknownObject is nullif("knownObject".equals(unknownObject)){ System.err.println("better coding avoided NullPointerException");}

這是最重要的避免NullPointException的java技巧胸墙,但是結(jié)果會(huì)是極大的改進(jìn)我注,因?yàn)閑qual()是一個(gè)很普遍的方法。

2)在兩者返回相同結(jié)果的時(shí)候偏向使用valueOf()而非toString()
因?yàn)榭諏?duì)象調(diào)用toString()時(shí)會(huì)拋出NullPointException迟隅。如果我們可以通過(guò)調(diào)用value()得到相同的值的話但骨,就應(yīng)該使用valueOf()。這樣會(huì)傳遞會(huì)一個(gè)空值智袭。特別是在像Integer嗽冒,F(xiàn)loat,Double或者BigDecimla之類的包裝類的情況下。

BigDecimal bd = getPrice();System.out.println(String.valueOf(bd)); //doesn’t throw NPESystem.out.println(bd.toString()); //throws "Exception in thread "main" java.lang.NullPointerException"

如果你不確定你所使用的對(duì)象是否是空的時(shí)候补履,請(qǐng)使用這個(gè)JAVA技巧

3)使用空安全方法(null safe method)或者類庫(kù)
現(xiàn)在有很多已經(jīng)為你做了null檢查的開源組件出現(xiàn)添坊。其中一個(gè)最為普遍的就是Apache的StringUtils。你可以使用StringUtils.isBlank(),isNumberic(),isWhiteSpace()和其他工具一些不用擔(dān)心NullPointException方法箫锤。

System.out.println(StringUtils.isEmpty(null));System.out.println(StringUtils.isBlank(null));System.out.println(StringUtils.isNumeric(null));System.out.println(StringUtils.isAllUpperCase(null));Output:truetruefalsefalse

但在作出任何結(jié)論之前贬蛙,不要忘記閱讀關(guān)于Null安全方法和類的文檔。這是另一個(gè)java最佳操練谚攒,這不會(huì)要求你付出非常多的努力阳准,但會(huì)讓你獲得很大的進(jìn)步。

4)避免用返回空的collection或者空的array來(lái)代替從方法中返回Null
這個(gè)java技巧也是在Joshua Bloch的《Effective Java》所提及的馏臭。這本書也是一個(gè)提高JAVA編碼能力的一個(gè)來(lái)源野蝇。通過(guò)返回一個(gè)空的collection或者一個(gè)空的array可以確定像size(),length()這種基礎(chǔ)的調(diào)用不會(huì)拋出NullPointException括儒。Collection類能夠提供方便的空的List绕沈,Set和Map,(這些)有Collections.EMPTY_LIST, Collections.EMPTY_SET和 Collections.EMPTY_MAP這些能夠被使用的(靜態(tài)變量)。
代碼如下;
public List getOrders(Customer customer){ List result = Collections.EMPTY_LIST; return result; }

類似地你可以使用Collections.EMPTY_LIST, Collections.EMPTY_SET和 Collections.EMPTY_MAP來(lái)代替返回Null帮寻。


5)使用@NotNull和@Nullable注釋
當(dāng)寫你可以定義關(guān)于約定可空性(Nullability)乍狐,要通過(guò)使用像@NotNull和@Nullable類似的注釋提示這個(gè)方法是否為空安全(null safe)。現(xiàn)代的編譯器固逗,IDE和其他工具可以讀出這個(gè)注釋來(lái)幫你做一個(gè)空檢查或者告訴你是否需要空檢查浅蚪。IntelliJIDE和findbugs 已經(jīng)支持這種注釋。這些注釋也是JSR 305(譯者注:可以理解為java的標(biāo)準(zhǔn))的一部分烫罩。通過(guò)看到@NotNull和@Nullable惜傲,程序猿可以自己決定是否去進(jìn)行空檢查。順便說(shuō)下贝攒,對(duì)于JAVA程序猿來(lái)說(shuō)盗誊,這是新的最好的實(shí)踐,盡管需要一點(diǎn)時(shí)間去適應(yīng)。


7)遵循約定和定義合理的默認(rèn)值
在java領(lǐng)域浊伙,一個(gè)最佳的避免空指針的方法之一就是和定下約定和遵守約定撞秋。大部分的NullPointException發(fā)生原因就是使用了一個(gè)不完整的信息或者并沒(méi)有被提供所有的依賴信息來(lái)創(chuàng)建對(duì)象。如果你不允許創(chuàng)建不完整的對(duì)象和否定任何這種要求嚣鄙,你可以預(yù)防很多一段時(shí)間之后發(fā)生的NullPointException吻贿。如果對(duì)象被允許創(chuàng)建,那么你應(yīng)該設(shè)定合理的默認(rèn)值哑子。例如舅列,一個(gè)Employee(雇員)對(duì)象不可以在沒(méi)有Id和Name屬性的情況下被創(chuàng)建,但可以有一個(gè)可供選擇的pghone number(電話號(hào)碼)卧蜓。如果Employee沒(méi)有phone number帐要,那么就用返回一個(gè)0來(lái)代替返回一個(gè)空值。但是這種處理必須非常小心地處理對(duì)空值的檢查而不是檢查非法輸入弥奸。同樣要注意榨惠,定義可以使空值的或者不可以空值的時(shí)候,提醒調(diào)用者作出被告知的決定盛霎。失敗之后的選擇或者接受空值也是一個(gè)你需要重視的重要設(shè)計(jì)赠橙。

8)如果你使用數(shù)據(jù)庫(kù)去存儲(chǔ)你的域?qū)ο螅╠emain object),例如:Customer愤炸、Orders等等期揪,那么你應(yīng)該定義一些在數(shù)據(jù)庫(kù)對(duì)空值的約束。因?yàn)閿?shù)據(jù)庫(kù)可以要求獲得從多個(gè)來(lái)源來(lái)的數(shù)據(jù)规个,在數(shù)據(jù)庫(kù)中擁有對(duì)空值的檢查將會(huì)確保數(shù)據(jù)的完整性凤薛。在數(shù)據(jù)庫(kù)中保留對(duì)空值約束的約束也是會(huì)讓你減少在JAVA中減少空檢查的代碼。當(dāng)從數(shù)據(jù)庫(kù)中取出一個(gè)對(duì)象是诞仓,你可以確保那些屬性可以是空而那些屬性不可以使空缤苫,這將會(huì)讓那些空檢查的代碼最小化。

9)使用空對(duì)象模式
這是另外一個(gè)在JAVA里面避免NullPointException的方法狂芋。如果一個(gè)方法返回一個(gè)對(duì)象榨馁,哪個(gè)調(diào)用者要遍歷這個(gè)對(duì)象,哪個(gè)調(diào)用者就要使用一些類似Collection.iterator()的方法去返回iterator帜矾。如果調(diào)用者沒(méi)有任何的上述的這些方法,那么有可能返回的是空對(duì)象而不是空(null)屑柔÷庞空對(duì)象是一個(gè)特別的對(duì)象,它在不同的上下文中有不同的含義掸宛。像這些返回Contrainter或者Conllection類型的方法的情況中死陆,里面為空的對(duì)象(Empty object)應(yīng)該被使用而不是返回空。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市措译,隨后出現(xiàn)的幾起案子别凤,更是在濱河造成了極大的恐慌,老刑警劉巖领虹,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件规哪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡塌衰,警方通過(guò)查閱死者的電腦和手機(jī)诉稍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)最疆,“玉大人杯巨,你說(shuō)我怎么就攤上這事∨幔” “怎么了服爷?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)获诈。 經(jīng)常有香客問(wèn)我仍源,道長(zhǎng),這世上最難降的妖魔是什么烙荷? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任镜会,我火速辦了婚禮,結(jié)果婚禮上终抽,老公的妹妹穿的比我還像新娘戳表。我一直安慰自己,他們只是感情好昼伴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布匾旭。 她就那樣靜靜地躺著,像睡著了一般圃郊。 火紅的嫁衣襯著肌膚如雪价涝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天持舆,我揣著相機(jī)與錄音色瘩,去河邊找鬼。 笑死逸寓,一個(gè)胖子當(dāng)著我的面吹牛居兆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竹伸,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼泥栖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起吧享,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤魏割,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后钢颂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钞它,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年甸陌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了须揣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钱豁,死狀恐怖耻卡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情牲尺,我是刑警寧澤卵酪,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站谤碳,受9級(jí)特大地震影響溃卡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜒简,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一瘸羡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搓茬,春花似錦犹赖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至锡凝,卻和暖如春粘昨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窜锯。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工张肾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锚扎。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓捌浩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親工秩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)助币,斷路器浪听,智...
    卡卡羅2017閱讀 134,638評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法眉菱,內(nèi)部類的語(yǔ)法迹栓,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法俭缓,線程的語(yǔ)...
    子非魚_t_閱讀 31,602評(píng)論 18 399
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等克伊,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,490評(píng)論 0 3
  • 一愿吹、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類型而言...
    龍貓小爺閱讀 4,257評(píng)論 0 16
  • 不知道平時(shí)做iOS端界面設(shè)計(jì)的同學(xué)有沒(méi)有一些困惑,就是在做完一個(gè)自己還挺滿意的界面時(shí)給身邊的人看惜姐,總是會(huì)聽到不同的...
    163study的設(shè)計(jì)思閱讀 1,676評(píng)論 0 11