第五十四條:返回零長(zhǎng)度的數(shù)組或者集合狱掂,而不是null

像下面的方法并不少見(jiàn):

// Returns null to indicate an empty collection. Don't do this!
private final List<Cheese> cheesesInStock = ...;
/**
* @return a list containing all of the cheeses in the shop, 
* or null if no cheeses are available for purchase.
*/
public List<Cheese> getCheeses() { 
  return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock); 
}

把沒(méi)有奶酪可買的情況當(dāng)作是一種特例子,這是不合理的始花。這樣做會(huì)要求客戶端中必須有額外的代碼來(lái)處理null返回值,例如:

List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && cheeses.contains(Cheese.STILTON))
  System.out.println("Jolly good, just the thing.");

對(duì)于一個(gè)返回null而不是零長(zhǎng)度數(shù)組或者集合的方法孩锡,幾乎每次用到該方法時(shí)都需要這種曲折的處理方式酷宵。這樣做很容易出錯(cuò),因?yàn)榫帉懣蛻舳顺绦虻某绦騿T可能會(huì)忘記寫這種專門的代碼來(lái)處理null返回值躬窜。這樣的錯(cuò)誤也許幾年都不會(huì)被注意到浇垦,因?yàn)檫@樣的方法通常返回一個(gè)或者多個(gè)對(duì)象。返回null而不是零長(zhǎng)度的容器荣挨,也會(huì)使返回該容器的方法實(shí)現(xiàn)代碼變得更加復(fù)雜男韧。

有時(shí)候會(huì)有人認(rèn)為:null返回值比零長(zhǎng)度集合或者數(shù)組更好朴摊,因?yàn)樗苊饬朔峙淞汩L(zhǎng)度的容器所需要的開銷。這種觀點(diǎn)是站不住腳的此虑,原因有兩點(diǎn)甚纲。第一,在這個(gè)級(jí)別上擔(dān)心性能問(wèn)題是不明智地朦前,除非分析表明這個(gè)方法正是造成性能問(wèn)題的真正源頭(詳見(jiàn)第67條)介杆。第二,不需要分配零長(zhǎng)度的集合或者數(shù)組韭寸,也可以返回它們春哨。下面是返回可能的零長(zhǎng)度集合的一段典型代碼。一般情況下恩伺,這些都是必須的:

//The right way to return a possibly empty collection
public List<Cheese> getCheeses() {
  return new ArrayList<>(cheesesInStock);
}

萬(wàn)一有證據(jù)表明分配零長(zhǎng)度的集合損害了程序的性能赴背,可以通過(guò)重復(fù)返回同一個(gè)不可變的零長(zhǎng)度集合,避免了分配的執(zhí)行晶渠,因?yàn)椴豢勺儗?duì)象可以被自由共享(詳見(jiàn)第17條)凰荚。下面的代碼正是這么做的,它使用了Collections.emptyList方法乱陡。如果返回的是集合浇揩,最好使用Collections.emptySet;如果返回的是映射憨颠,最好使用Collections.emptyMap胳徽。但是要記住,這是一個(gè)優(yōu)化爽彤,并且?guī)缀跤貌簧涎痢H绻阏J(rèn)為確實(shí)需要,必須在行動(dòng)前后分別測(cè)試測(cè)量性能适篙,確保這么做確實(shí)是有幫助的:

// Optimization - avoids allocating empty collections
public List<Cheese> getCheeses() {
  return cheesesInStock.isEmpty() ? Collections.emptyList() : new ArrayList<>(cheesesInStock); 
}

數(shù)組的情形與集合的情形一樣往核,它永遠(yuǎn)不會(huì)返回null,而是返回零長(zhǎng)度的數(shù)組嚷节。一般來(lái)說(shuō)聂儒,應(yīng)該只返回一個(gè)正確長(zhǎng)度的數(shù)組,這個(gè)長(zhǎng)度可以為零硫痰。注意衩婚,我們將一個(gè)零長(zhǎng)度的數(shù)組傳遞給了toArray方法,以指明所期望的返回類型效斑,即Cheese[]:

//The right way to return a possibly empty array
public Cheese[] getCheeses() {
  return cheesesInStock.toArray(new Cheese[0]);
}

如果確信分配零長(zhǎng)度的數(shù)組會(huì)傷害性能非春,可以重復(fù)返回同一個(gè)零長(zhǎng)度的數(shù)組,因?yàn)樗辛汩L(zhǎng)度的數(shù)組都是不可變的:

// Optimization - avoids allocating empty arrays
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
  return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}

在優(yōu)化性能的版本中,我們將同一個(gè)零長(zhǎng)度的數(shù)組傳進(jìn)了每一次的toArrya調(diào)用奇昙,每當(dāng)cheesesInStock為空時(shí)护侮,就會(huì)從getCheese返回這個(gè)數(shù)組。千萬(wàn)不要指望通過(guò)預(yù)先分配傳入toArray的數(shù)組來(lái)提升性能储耐。研究表明羊初,這樣只會(huì)適得其反:

// Don’t do this - preallocating the array harms performance!
return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]);

簡(jiǎn)而言之,永遠(yuǎn)不要返回null弧岳,而不會(huì)一個(gè)零長(zhǎng)度的數(shù)組或者集合凳忙。如果返回null,那么會(huì)使API更難使用禽炬,也更容易出錯(cuò)涧卵,而且沒(méi)有任何性能優(yōu)勢(shì)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腹尖,一起剝皮案震驚了整個(gè)濱河市柳恐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌热幔,老刑警劉巖乐设,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绎巨,居然都是意外死亡近尚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門场勤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)戈锻,“玉大人,你說(shuō)我怎么就攤上這事和媳「裨猓” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵留瞳,是天一觀的道長(zhǎng)拒迅。 經(jīng)常有香客問(wèn)我,道長(zhǎng)她倘,這世上最難降的妖魔是什么璧微? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮硬梁,結(jié)果婚禮上前硫,老公的妹妹穿的比我還像新娘。我一直安慰自己靶溜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罩息,像睡著了一般嗤详。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓷炮,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天葱色,我揣著相機(jī)與錄音,去河邊找鬼娘香。 笑死苍狰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烘绽。 我是一名探鬼主播淋昭,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼安接!你這毒婦竟也來(lái)了翔忽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盏檐,失蹤者是張志新(化名)和其女友劉穎歇式,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胡野,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡材失,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硫豆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片龙巨。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖够庙,靈堂內(nèi)的尸體忽然破棺而出恭应,到底是詐尸還是另有隱情,我是刑警寧澤耘眨,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布昼榛,位于F島的核電站,受9級(jí)特大地震影響剔难,放射性物質(zhì)發(fā)生泄漏胆屿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一偶宫、第九天 我趴在偏房一處隱蔽的房頂上張望非迹。 院中可真熱鬧,春花似錦纯趋、人聲如沸憎兽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纯命。三九已至西剥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亿汞,已是汗流浹背瞭空。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疗我,地道東北人咆畏。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吴裤,于是被迫代替她去往敵國(guó)和親旧找。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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