譯文:我們?yōu)槭裁磹勰?-null(2.方案“零”)

【譯者序】
前一篇文章中原文作者漫談了null的來源與引發(fā)的常見問題,本文將開始對3中如今流行的null處理方式進(jìn)行討論,首先討論第一種方案

使用0來代替null

假設(shè)我們正在做一個(gè)在線購物的應(yīng)用,用戶可以在線下單購買商品。店家可以發(fā)布新商品,當(dāng)然當(dāng)這個(gè)新商品的價(jià)格還未定的時(shí)候,可以不填價(jià)格,先發(fā)布商品。

對于這個(gè)業(yè)務(wù)場景,下面哪種方案更好:

-- 不允許用戶讓價(jià)格為null,這樣可以完全阻止空指針錯(cuò)誤的發(fā)生。如果這個(gè)價(jià)格當(dāng)下確實(shí)未定,那就填0好了;

-- 如果價(jià)格當(dāng)下還未知,那就存null好了,給null敞開大門一次吧。

如果你去看看Stackoverflow上的這個(gè)問答——“用null還是用空集合”,你會發(fā)現(xiàn)這個(gè)問題的答案驚人的一致。

很多程序猿不知道怎么來區(qū)別處理“空”與“零”的關(guān)系,在我看來,若處理不當(dāng),這里面還會暗藏著嚴(yán)重的危機(jī)。比如,我一年多前想買個(gè)房子。我去一個(gè)房地產(chǎn)的網(wǎng)站,然后發(fā)現(xiàn)上面有很多房子的價(jià)格寫著“0”。可把我樂壞了:“沒逗我吧?免費(fèi)送房子??”但我當(dāng)然明白現(xiàn)實(shí)是殘酷的——他們只是沒寫價(jià)格而已。在這個(gè)例子里,你可能會毫不猶豫的說:“這還用問嗎?肯定是沒寫價(jià)格啊,誰沒事吃飽了撐著給你送房子啊。”

但是這網(wǎng)站上其他很多房子卻有寫了售價(jià),而且還有總體平均價(jià)格這些數(shù)據(jù)。我不知道這些均價(jià)計(jì)算里有沒有包括“0”,這樣一來搞不好會產(chǎn)生很多錯(cuò)誤。換句話說,100,000、120,000 和 “未知”,這三個(gè)的均價(jià)是多少?技術(shù)上來說當(dāng)然應(yīng)該是回答“未知”了。但你覺得這是用戶想看到的數(shù)據(jù)嗎?我們當(dāng)然希望看到的是明確的價(jià)格數(shù)字,像110,000這樣,但弄不好到頭來整出個(gè)73,333(這個(gè)數(shù)據(jù)我不知道原作者怎么突然冒出來的--譯者),那顯然是瞎扯淡了。而且,這個(gè)問題如果一旦發(fā)生在能夠在線支付的網(wǎng)站,那后果不堪設(shè)想。難道我們真的希望把“價(jià)格未定”弄得像“免費(fèi)”一樣?

用戶Jay這么說的:

我經(jīng)常弄不明白這個(gè)0和“無答案”之間的區(qū)別。許多次了,我用一個(gè)系統(tǒng)的時(shí)候它讓我輸入一個(gè)數(shù)字,我輸入0,然后它居然回我一個(gè)錯(cuò)誤,說我必須輸入一個(gè)值!?耍我呢?我不是已經(jīng)輸入了0么?但它就死活說0不行,我估計(jì)是因?yàn)樗九磺宄?和“無”之間的區(qū)別。

那如果我們采用第二種保留null的方案的話,網(wǎng)上商店會運(yùn)行得怎樣?很明顯,價(jià)格為0、莫名其妙的“零元購”將會被從根本上杜絕。

我們可以去對null做一個(gè)檢查,如果價(jià)格為null,那么顯示“價(jià)格未定”或者“請聯(lián)系我們”。如果忘記檢查了,那就會拋出另一個(gè)空指針錯(cuò)誤。這種做法當(dāng)然不討人喜歡,但是再怎么也比讓用戶在網(wǎng)上莫名其妙的免費(fèi)買房子要好。

這樣一來,均價(jià)的計(jì)算也不會出現(xiàn)問題了。

除了這些外,我們還可以發(fā)現(xiàn)更多與之類似的問題:

· 在使用String的時(shí)候,用空字符串或者用字符串"null"來代替本應(yīng)該是null的值

· 在使用boolean的時(shí)候,用false來代替本應(yīng)該是null的值

縱觀全局,總結(jié)如下:

保持用null,遠(yuǎn)比用非null的值來替代“無值”要好

沒錯(cuò),我們是增加了空指針錯(cuò)誤的風(fēng)險(xiǎn)。但是為了避免這種錯(cuò)誤,我們所付出的代價(jià)就是直接給用戶提供完全錯(cuò)誤的信息,甚至導(dǎo)致完全無法接受乃至災(zāi)難性的后果——比如房子突然被免費(fèi)“賣”出去了。

-- 如果程序因?yàn)榭罩羔樺e(cuò)誤崩潰了,用戶的確會不高興;

-- 但如果程序完全傳達(dá)錯(cuò)誤的信息并且提供極其愚蠢、不安全的信息給用戶,那用戶,會更加更加不高興。

-- 孰輕孰重,一目了然。

所以,我們真的需要對null說一聲愛你。


好了,這時(shí)候我們回到剛一開始我介紹的email的例子上來。我們?nèi)缦略O(shè)置:

String email = null;
System.out.println ( "Alice's email address is " + email );

有如下結(jié)果:

Alice's email address is null

在這個(gè)場景里,這個(gè)結(jié)果看起來還是可以接受的。但說實(shí)在的程序語言/編譯器不應(yīng)該這么來處理。像我們剛剛分析了,更好的做法應(yīng)該是拋出一個(gè)空指針異常,因?yàn)檫@樣一來程序員就可以很快的發(fā)現(xiàn)這里有問題。null是個(gè)很特殊的東西,所以我們也有必要去對它特殊對待。

經(jīng)過空指針錯(cuò)誤的提醒,程序猿這么一改,就舒服了:

if ( email != null ) {
   System.out.println ( "Alice's email address is " + email );
} else {
   System.out.println ( "Alice doesn't have an email address." );
}

【下一篇文章將分析第二種方案:空對象模式】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

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