使用Optional優(yōu)雅處理null

先假設(shè)一個場景衣屏。如下所示

public class Person {

    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

我們有一個Person類躏升,有一個屬性是name。有如下代碼:

public static void main(String[] args) {
    Person person = new Person();

    String name = person.getName();

    if (name.equals("Jackson")) {
        System.out.println("My name is Jackson!");
    }
}

我們判斷獲取person的name狼忱,然后判斷person的name是不是Jackson膨疏。因為person的name為null,所以name.equals("Jackson")這段代碼會報空指針的異常钻弄。

我們有多種方式來處理空指針的異常佃却,一種是我們考察我們的業(yè)務(wù)邏輯,當(dāng)需要返回一個null值時返回一個有意義的NullObject窘俺。例如空字符串對應(yīng)返回字符串的情況饲帅,空列表對應(yīng)返回list的情況,對一些特殊的對象,可以根據(jù)不同的業(yè)務(wù)邏輯創(chuàng)建一些Null對象灶泵。參考《Effictive Java》第43條育八,《重構(gòu)》9.7節(jié)。

對于我們的例子赦邻,當(dāng)name為null時髓棋,getName方法返回一個""字符串。當(dāng)接下來取出name來進(jìn)行操作時就不會出現(xiàn)空指針的異常惶洲。

public String getName() {
    if (name == null) {
        return "";
    } else {
        return name;
    }
}

另一種是在調(diào)用的時候判斷是否為空按声,對于我們的例子,如下代碼:

if (name != null && name.equals("Jackson")){}

通過判斷name是否為空湃鹊,若非空再判斷name是否等于Jackson儒喊。通過這樣的方式可以解決空指針異常的問題。

但是兩種方案都有一定的缺點币呵,對于第一種方案,String和集合類型的Null對象很好確認(rèn)侨颈,就是空字符串和空集合余赢。但是對于一些特殊的對象,創(chuàng)建Null對象需要更多的步驟哈垢,更多的設(shè)計妻柒。總之就是兩個字耘分,麻煩举塔。

對于第二種方案,這個也是我們最常用的求泰。但是這個方案有一個問題央渣,就是經(jīng)常會忘記判空。對于一個方法other.method(a, b),我們常常不會忘記對a和b進(jìn)行判空渴频,而對方法的返回值卻經(jīng)常忘記判空芽丹。而這個空指針異常是在運行時才會被發(fā)現(xiàn),如果空指針的情況十分的罕見卜朗,那么很可能很長一段時間都不會發(fā)現(xiàn)這個異常拔第。我常常碰到的一種情況是當(dāng)數(shù)據(jù)庫中存在臟數(shù)據(jù)的時候,正常的數(shù)據(jù)是不應(yīng)該存在null的场钉,但是即使是生產(chǎn)環(huán)境也很有可能混入一兩個臟數(shù)據(jù)蚊俺,很可能這罕見的臟數(shù)據(jù)導(dǎo)致程序報錯」渫颍可能這個時候再去修復(fù)bug泳猬,代價比開發(fā)階段高很多。

為了優(yōu)雅地處理null的情況,可以使用google guava的Optional暂殖。API不說了价匠,直接上代碼

public class Person {

    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public Optional<String> getName() {
        return Optional.fromNullable(name);
    }

    public static void main(String[] args) {
        Person person = new Person();

        Optional<String> optionalName = person.getName();
        if (optionalName.isPresent()) {
            String name = optionalName.get();
            System.out.println("My name is :" + name);
        } else {
            System.out.println("Who am I?");
        }
    }
}

在getName里,我們由原來直接返回name呛每,改成返回Optional<String>踩窖。通過Optional.fromNullable(T)靜態(tài)方法,可以創(chuàng)建一個Optional對象晨横。如果傳入的對象是null洋腮,那么isPresent返回false,否則返回true手形。在上訴代碼中啥供,Person的name沒有設(shè)置,optionalName.isPresent()返回的是false库糠,所以打印出的應(yīng)該是Who am I?伙狐。

從代碼上看,這個和第二種方案瞬欧,對對象判空的方法沒有區(qū)別贷屎,都是先判斷是否存在,然后再對對象進(jìn)行操作艘虎。我起初也是百思不得其解唉侄,后來在在stackoverflow發(fā)現(xiàn)一篇回答,What's the point of Guava's Optional class野建。我個人的感覺是属划,因為我們沒法直接獲取所需的對象,而是獲得Optional對象候生,需要從Optional中獲取我們需要的對象同眯,所以我們就不會忘了判空這步操作了。因為不判空取不到所需對象陶舞,google也是挺會幫程序員克服遺忘的啊嗽测。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市肿孵,隨后出現(xiàn)的幾起案子唠粥,更是在濱河造成了極大的恐慌,老刑警劉巖停做,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晤愧,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛉腌,警方通過查閱死者的電腦和手機(jī)官份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門只厘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硫戈,“玉大人盯仪,你說我怎么就攤上這事∏穑” “怎么了钠右?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵赋元,是天一觀的道長。 經(jīng)常有香客問我飒房,道長搁凸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任狠毯,我火速辦了婚禮护糖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嚼松。我一直安慰自己嫡良,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布献酗。 她就那樣靜靜地躺著皆刺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凌摄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天漓帅,我揣著相機(jī)與錄音锨亏,去河邊找鬼。 笑死忙干,一個胖子當(dāng)著我的面吹牛器予,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捐迫,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼乾翔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了施戴?” 一聲冷哼從身側(cè)響起反浓,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赞哗,沒想到半個月后雷则,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡肪笋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年月劈,在試婚紗的時候發(fā)現(xiàn)自己被綠了度迂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡猜揪,死狀恐怖惭墓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情而姐,我是刑警寧澤腊凶,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站毅人,受9級特大地震影響吭狡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丈莺,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一划煮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缔俄,春花似錦弛秋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遏佣,卻和暖如春挖炬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背状婶。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工意敛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膛虫。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓草姻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稍刀。 傳聞我的和親對象是個殘疾皇子撩独,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)账月,斷路器综膀,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • Optional 本章內(nèi)容 如何為缺失的值建模 Optional 類 應(yīng)用Optional的幾種模式 使用Opti...
    追憶逝水年華閱讀 1,783評論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法捶障,內(nèi)部類的語法僧须,繼承相關(guān)的語法,異常的語法项炼,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • 2014年的蘋果全球開發(fā)者大會(WWDC)担平,當(dāng)Craig Federighi向全世界宣布“We have new ...
    yeshenlong520閱讀 2,267評論 0 9
  • 他是一個建筑工地的工人示绊,有一個美麗的妻子,還有一個漂亮的女兒暂论,女兒五歲多了面褐,很幸福的一家,為了這個家他在工地上干最...
    旅行新起點閱讀 137評論 0 0