合理地處理null值

不好的做法

在定義并實(shí)現(xiàn)一個(gè)方法時(shí)藕漱,如果返回值是一個(gè)引用類型的對(duì)象,那么這個(gè)對(duì)象的值是有可能為null的,而方法的調(diào)用者在調(diào)用的時(shí)候就需要考慮返回值為null的情況,進(jìn)行單獨(dú)處理娩践。這樣就常常會(huì)出現(xiàn)類似于如下的代碼:

public static void main(String[] args) {
    List<String> stringList = getList();
    if(stringList != null){
        System.out.println("Size of stringList :" + stringList.size());
    }else{
        System.out.println("Size of stringList :" + 0);
    }
}
public static List<String> getList() {
    return null;
}

可以看到對(duì)于方法的調(diào)用者而言,需要考慮返回值為null的情況烹骨,這樣的設(shè)計(jì)不利于代碼的整潔翻伺。

方法應(yīng)盡量返回空集合或空對(duì)象,而非null

比較好的做法是展氓,對(duì)于方法的定義和實(shí)現(xiàn)者而言穆趴,盡量保證方法的返回值不返回null值,而是返回相應(yīng)的“空對(duì)象”來(lái)代替null值遇汞。比如下面的代碼:

static List<String> getList2(){
    List<String> stringList = null;
    if(stringList == null){
        return Collections.EMPTY_LIST;
    }
    return stringList;
}
static List<String> getList3(){
    List<String> stringList = null;
    return Optional.fromNullable(stringList).or(Collections.EMPTY_LIST);
}

public static void main(String[] args) {
    List<String> stringList2 = getList2();
    System.out.println("Size of stringList2 :" + stringList2.size());

    List<String> stringList3 = getList3();
    System.out.println("Size of stringList3 :" + stringList3.size());
}

這樣的實(shí)現(xiàn)有兩種方式:

  1. getList2()所示:直接判斷返回值是否==null,如果是簿废,則返回一個(gè)空集合空入。這樣的做法很直觀,但不推薦族檬。在程序中應(yīng)盡量避免對(duì)null值的直接判斷歪赢。
  2. getList3()所示:通過(guò)使用Guava的Optional工具來(lái)對(duì)返回的對(duì)象進(jìn)行處理。推薦這種做法

同樣道理单料,對(duì)于返回值是String類型時(shí)埋凯,如果遇到null值,可以返回空串("")代替之扫尖。當(dāng)然白对,同樣可以使用通用的Guava庫(kù)來(lái)返回默認(rèn)值(String也是對(duì)象),也可以直接使用StringUtils來(lái)返回默認(rèn)的字符串换怖。如下面的例子:

public static void main(String[] args) {
    String string1 = getString1();
    System.out.println("string1 :" + string1);
}
static String getString1(){
    String string = null;
    return Optional.fromNullable(string).or(StringUtils.EMPTY);
    // or ...
    // return StringUtils.defaultString(string);
}

對(duì)于需要區(qū)分null值的和空值的方法甩恼,將返回值的類型用Optional包裝,而非直接返回

對(duì)于有些場(chǎng)景沉颂,方法的調(diào)用者有可能需要區(qū)分null值和空值來(lái)進(jìn)行不同的行為条摸,那么也不要直接返回,而是通過(guò)Guava的Optional工具進(jìn)行包裝铸屉。如下面的例子所示:

public static void main(String[] args) {
    List<String> stringList1 = getList1().or(Collections.EMPTY_LIST);
    System.out.println("Size of stringList1 :" + stringList1.size());
}
static Optional<List<String>> getList1(){
    // 從數(shù)據(jù)庫(kù)里取到null值
    List<String> stringList = null;
    return Optional.fromNullable(stringList);
}

這樣做的好處是钉蒲,方法的調(diào)用者拿到的是返回值包裝后的對(duì)象,它需要被解包后才能使用彻坛。這樣可以迫使方法的調(diào)用者考慮對(duì)象缺失-absent(null值)的情況顷啼,而不是忘記處理后帆赢,在運(yùn)行時(shí)再拋出NullPointerException。

其它好的實(shí)踐

  1. 在對(duì)String進(jìn)行操作的時(shí)候线梗,盡量使用一些第三方的庫(kù)(如:Apache commons-lang3)椰于。因?yàn)檫@些庫(kù)方法的實(shí)現(xiàn)中,處理了null值的情況仪搔。
  2. 在對(duì)字符串進(jìn)行String.equals()方法進(jìn)行兩個(gè)字符串判等的時(shí)候瘾婿,將已知的字符串放在前面,將未知的變量作為方法的參數(shù)烤咧,放在后面偏陪。
    如下面的代碼會(huì)拋出NullPointerException:
String knownStr = "123";
String unknownStr = null;
if(unknownStr.equals(knownStr)){
    // ... do something
}

如果將knownStr放在前面,就可以避免這個(gè)異常:

String knownStr = "123";
String unknownStr = null;
if(knownStr.equals(unknownStr)){
    // ... do something
}
  1. 在定義POJO的時(shí)候煮嫌,將所有的域都初始化合理的默認(rèn)值笛谦。
  2. 如果對(duì)于一個(gè)對(duì)象obj,要取其對(duì)應(yīng)的字符串的值昌阿,那么盡量使用String.valueOf(obj)饥脑,而非obj.toString()
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

源碼可見懦冰,String.valueOf(obj)進(jìn)行了null值的判斷灶轰,對(duì)于null值返回字符串"null"。這樣雖然可以避免異常刷钢,但是未必符合業(yè)務(wù)需要笋颤。因此,推薦使用StringUtils的defaultString()方法來(lái)處理内地,其專門用于處理String為null的情況的缺省值:

public static String defaultString(final String str) {
    return str == null ? EMPTY : str;
}
public static String defaultString(final String str, final String defaultStr) {
    return str == null ? defaultStr : str;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伴澄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子阱缓,更是在濱河造成了極大的恐慌非凌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茬祷,死亡現(xiàn)場(chǎng)離奇詭異清焕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)祭犯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門秸妥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沃粗,你說(shuō)我怎么就攤上這事粥惧。” “怎么了最盅?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵突雪,是天一觀的道長(zhǎng)起惕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咏删,這世上最難降的妖魔是什么惹想? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮督函,結(jié)果婚禮上嘀粱,老公的妹妹穿的比我還像新娘。我一直安慰自己辰狡,他們只是感情好锋叨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宛篇,像睡著了一般娃磺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叫倍,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天偷卧,我揣著相機(jī)與錄音,去河邊找鬼段标。 笑死涯冠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逼庞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼瞻赶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼赛糟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起砸逊,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤璧南,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后师逸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體司倚,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年篓像,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了动知。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡员辩,死狀恐怖盒粮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奠滑,我是刑警寧澤丹皱,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布妒穴,位于F島的核電站,受9級(jí)特大地震影響摊崭,放射性物質(zhì)發(fā)生泄漏讼油。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一呢簸、第九天 我趴在偏房一處隱蔽的房頂上張望矮台。 院中可真熱鬧,春花似錦阔墩、人聲如沸嘿架。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)耸彪。三九已至,卻和暖如春忘苛,著一層夾襖步出監(jiān)牢的瞬間蝉娜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工扎唾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留召川,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓胸遇,卻偏偏與公主長(zhǎng)得像荧呐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纸镊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法倍阐,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法逗威,繼承相關(guān)的語(yǔ)法峰搪,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,663評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理凯旭,服務(wù)發(fā)現(xiàn)概耻,斷路器,智...
    卡卡羅2017閱讀 134,701評(píng)論 18 139
  • 源碼:https://github.com/joshul/seckill開始Service層的編碼之前罐呼,我們首先需...
    joshul閱讀 1,978評(píng)論 0 2
  • 來(lái)到日本不知不覺已經(jīng)快要半年了鞠柄。我依然念念不忘自己曾經(jīng)那些想要做的事,二十歲弄贿,我錯(cuò)過(guò)了它開始的象征性的那天春锋,也忘了...
    吉安睡不著閱讀 157評(píng)論 0 0
  • 為什么要學(xué)習(xí)寫作? 自從開啟元認(rèn)知差凹,發(fā)現(xiàn)自己大腦就是一團(tuán)漿糊期奔,通過(guò)學(xué)習(xí)得知侧馅,這是因?yàn)榇竽X儲(chǔ)備的清晰準(zhǔn)確的概念太少。...
    東涂西抹閱讀 283評(píng)論 0 0