當前位置:
首頁 > 最新 > Java 8:遠離萬惡之 null

Java 8:遠離萬惡之 null

Java 8 推出 3 年多了,但直到這周我才知道什麼是 Optional ……

Java 程序員經常會碰到一個讓人心煩的錯誤 : NullPointerException

尤其是和別人合作時,像我一樣的 Java 小白經常會糾結調用的方法會不會有 null value。

如果不去檢查,程序很可能運行到一半因為返回 null 而報錯閃退,對用戶的體驗帶來極大影響。如果對於每個返回值都去檢查,程序看起來會特別的難過……

舉個例子

假設我們這個周末要開一個盛大的 party,要準備的東西很多,包括必不可少的一長串酒單需要購買。組織者里正好有一位 Java 程序員,他很熱心,表示願意幫大家分擔些負擔,於是寫了一個自動準備宴會的系統。

代碼很簡單,用了 Drink,Store,DrinkOrder 三個 class 來輔助買酒的任務執行。

Drink 和 DrinkOrder 用來存要買的酒的信息。

Store class 有兩個方法:

int getDrinkPrice(String drinkName) : 根據輸入的 Drink 名稱,查看商店裡對應酒的價錢,如果該商品不存在,返回 -1。

void order(String drinkName, String drinkQuantity) : 根據輸入 Drink 的名稱和數量,自動下單。

主程序 PreparationSystem 存儲了一個所有 Store 的列表,還有三個方法:

List generateDrinkOrder() : 輔助邏輯,生成一個固定的酒單

Store findCheapestStore(String drinkName) : 輔助邏輯,根據輸入 Drink 的名稱,從已有的 Store 列表中,找到賣這種酒最便宜的商店

void prepareParty() : 主要邏輯,生成酒單,並根據酒單,花最少的價錢去買酒

這樣寫出來的代碼乍一看沒有什麼問題,但是如果生成的固定酒單中有一款非常不常見的酒 (比如說 Xtabentún ),導致 findCheapestStore 因為列表中所有的商店都沒有這種酒而返回 null,這樣程序執行到 「store.order」 的時候就會拋出 NullPointerException 的異常。

簡單的做法是在 prepareParty 里加一層對 null 值的檢測:

但這樣寫代碼寫多了滿屏都是 null,很不好維護。另外,對於什麼樣的方法要進行不為 null 的檢查也沒有足夠明確的說明。

解決方法一般有兩個,一個是加 @NotNull 的注釋 (感興趣的小夥伴自行上網查),另一個在 Java 8 中可以用的是 java.util.Optional

官方 API 對 Optional 的聲明 :

A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

因為是一個容器類型,所以想用 Optional 的話,只需要很簡單地將 findCheapestStore 的返回值從 Store 改為 Optional ,並且把返回的 cheapestStore 用 Optional 的靜態方法包裝一下就好。

更改之後的代碼如下:

相應的,prepareParty 的 for loop 就不需要對 null 值進行檢測:

如果真的有人在看代碼的話,你會說 「 誒,這tm不和直接 check null 一樣嗎,只不過把 != null 改成了 isPresent() 」。

你講的很有道理,這麼寫確實就沒有區別了,反而使代碼更加複雜,所以推薦的是用 Optional 里的 ifPresent 方法。

用 lambda 表達式改寫後的 for loop :

是不是比總去檢查 null 更簡潔易懂好維護了呢?

吐槽一下 : 微信公眾號改代碼格式太困難了……

原創開通了就不放二維碼求關注了,不過安卓的小夥伴應該能看到點不同的東西 ( 手動滑稽 )。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 公眾號 的精彩文章:

憑什麼女追男就沒有好下場?
不要老拿自己是「女人」說事兒
期待Star Rose的綻放
返樸:我把憂傷塵封在盒子里
婚姻最怕宮星同位

TAG:公眾號 |