讀Java實戰(第二版)筆記07_用Optional取代null

来源:https://www.cnblogs.com/lying7/archive/2023/02/12/17108974.html
-Advertisement-
Play Games

1基礎知識 機器語言是機器指令的集合,由0和1組成,但是很長很複雜,彙編語言因此產生。 彙編語言的主體是彙編指令。彙編指令是機器指令的便於記憶的書寫格式。 程式員寫完彙編指令通過編譯器轉換為機器碼,機器碼再傳到電腦執行。 彙編語言有以下三類: 1彙編指令:助記符,有對應機器碼 2.偽指令:沒有對應 ...


1. null的由來

1.1. 歷史上被引入到程式設計語言中,目的是為了表示變數值的缺失

1.2. 包括Java在內的大多數現代程式設計語言為了與更老的語言保持相容

2. null帶來的問題

2.1. 錯誤之源

2.1.1. NullPointerException是最典型的異常

2.2. 代碼膨脹

2.2.1. 深度嵌套的null檢查

2.3. 自身毫無意義

2.3.1. 自身沒有任何的語義

2.3.2. 以一種錯誤的方式對缺失變數值的建模

2.4. 破壞了Java的哲學

2.4.1. 讓程式員意識到指針的存在

2.4.2. null指針

2.5. 在類型系統上開了個口子

2.5.1. null並不屬於任何類型

2.5.2. null可被賦值給任意引用類型的變數

3. 防禦式檢查NullPointerException

3.1. 深層質疑

3.1.1. 每次你不確定一個變數是否為null時,都需要添加一個進一步嵌套的if塊,這也增加了代碼縮進的層數

3.2. 過多的退出語句

3.2.1. 為了避免深層遞歸的if語句塊

3.2.2. 但這種流程是極易出錯的

4. null的替代品

4.1. Groovy

4.1.1. 安全導航操作符(safe navigation operator,標記為?)

4.1.2. 可以安全訪問可能為null的變數

4.1.3. 掩耳盜鈴

4.2. Haskell

4.2.1. Maybe類型

4.2.1.1. 對Optional值的封裝

4.2.1.2. 可以是指定類型的值

4.2.1.3. 可以什麼都不是

4.3. Scala

4.3.1. Option[T]

4.3.1.1. 顯式地調用Option類型的available操作,檢查該變數是否有值

4.3.1.1.1. 變相的“null檢查”
4.3.1.1.2. 類型系統預設會強制進行檢查

4.3.1.2. 可以包含類型為T的變數

4.3.1.3. 可以不包含該變數

4.4. Java

5. java.util.Optional

5.1. 封裝Optional值的類

5.1.1. 對存在或缺失的變數值進行建模

5.1.2. 用戶只需要閱讀方法簽名,就能瞭解該方法是否接受一個Optional類型的值

5.1.3. 不再需要為其添加null的檢查

5.1.3.1. 因為null的檢查只會掩蓋問題,並未真正地修複問題

5.2. 清晰界定變數值缺失原因

5.2.1. 結構上的問題

5.2.2. 演算法上的缺陷

5.2.3. 數據中的問題

5.3. 設計初衷僅僅是要支持能返回Optional對象的語法

5.3.1. 沒特別考慮將其作為類的欄位使用

5.3.2. 並未實現Serializable介面

5.3.2.1. 替代方案提供一個能訪問聲明為Optional、變數值可能缺失的介面

5.4. Optional.empty

5.4.1. 聲明一個空的Optional

5.4.2. 變數不存在時返回Optional類的特定單一實例

5.5. Optional.of

5.5.1. 依據一個非空值創建Optional

5.6. Optional.ofNullable

5.6.1. 可接受null的Optional

5.6.2. 創建一個允許null值的Optional對象

5.7. get()

5.7.1. 最簡單但又最不安全的方法

5.7.2. 拋出一個NoSuchElementException異常

5.8. orElseThrow(Supplier<? extends="" x=""? > exceptionSupplier)

5.8.1. 類似get方法

5.8.2. 定製希望拋出的異常類型

5.9. orElse(T other)

5.9.1. Optional對象不包含值時提供一個預設值

5.10. orElseGet(Supplier<? extends="" t=""? > other)

5.10.1. orElse方法的延遲調用版

5.10.2. Supplier方法只有在Optional對象不含值時才執行調用

5.10.3. 應用場景

5.10.3.1. 創建預設值是件耗時費力的工作,藉此提升程式的性能

5.10.3.2. 非常確定某個方法僅在Optional為空時才進行調用

5.11. or(Supplier<? extends=""? ><? extends="" t=""? >> supplier)

5.11.1. Java9

5.11.2. 類似orElseGet方法

5.11.3. 不會解包Optional對象中的值,即便該值是存在的

5.12. ifPresent(Consumer<? super="" t=""? >consumer)

5.12.1. 變數值存在時,執行一個以參數形式傳入的方法

5.12.2. 變數值不存在時,就不進行任何操作

5.13. ifPresentOrElse(Consumer<? super="" t=""? > action, Runnable emptyAction)

5.13.1. Java9

5.13.2. 接受一個Runnable方法,如果Optional對象為空,就執行該方法所定義的動作

5.14. 和Stream介面的相似之處

5.14.1. map方法

5.14.1.1. 使用map從Optional對象中提取和轉換值

5.14.2. flatMap方法

5.14.2.1. 使用flatMap鏈接Optional對象

5.14.3. filter方法

5.14.3.1. 使用filter剔除特定的值

5.15. 操縱由Optional對象構成的Stream

5.15.1. Java9

5.15.2. 把一個含值的Optional對象轉換成由該值構成的Stream對象

5.15.3. 把一個空的Optional對象轉換成等價的空Stream

5.16. 基礎類型的Optional對象

5.16.1. OptionalInt

5.16.2. OptionalLong

5.16.3. OptionalDouble

5.16.4. 不推薦

5.16.4.1. Optional對象最多只包含一個值

5.16.4.2. 基礎類型的Optional不支持map、flatMap以及filter方法


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 「CSDN」作為中國最具人氣的專業 IT 社區,一直是廣大 IT 技術博主的主選陣地。這些年 CSDN 在知識付費領域的探索也遠遠超過其它平臺,大家(尤其是創作型博主)對 CSDN 的認可度也越來越高,CSDN 上目前有很多非常優秀的技術專欄。 CSDN博客專家 是 CSDN 給予影響力較大的技術類 ...
  • 前言 AppImage 逐漸成為 Linux 常用的一種軟體包格式,本文將介紹如何將 AppImage 文件添加到 Ubuntu 的應用程式中。 如下圖中的 CAJViewer : 操作過程 設置相關許可權 對要操作的 AppImage 右擊 > 屬性進行如下圖的設置,必須勾選 允許執行文件 創建 d ...
  • JLink RTT(Real Time Transfer) 是用於嵌入式系統監控和交互的工具, 類似於SWO, 可以雙向通信, 特點是性能很高, 基本上不影響嵌入式應用的實時行為, 可以對比一下使用printf輸出日誌時的各種限制. 而且因為和 JLink 介面集成, 不需要再浪費一個串口輸出 pr... ...
  • PY32F002A, PY32F003, PY32F030 三個系列硬體相同, 下麵以 PY32F030的時鐘樹結構為例說明 內部時鐘有32KHz和24MHz(從代碼上看其實是8MHz),外部時鐘是直接接入, PLL只有2倍. 使用外置晶振時如果要達到標稱的48MHz, 晶振頻率就必須用24MHz,... ...
  • 為什麼會選擇Pop!_os 剛決定使用Linux系統的時候想的肯定是用Arch Linux(不得不說ArchWiki太NB了),但是遇到兩個麻煩沒有解決:1.連上wifi後發現沒有分配IPv4地址,google了一圈都沒找到解決方法。於是放棄了。2.第二次嘗試安裝Arch(主要是第一次安裝失敗後,心 ...
  • 使用JS的DOM(文檔對象模型)獲取前端迴圈的參數 使用Go語言渲染html,但是想讓網頁動起來,顯示一些彈窗還是比較麻煩的,於是乎,想到使用js獲取頁面的數據進行顯示,但是js無法載入go的一些變數。想了很久,突然在網頁調試的時候使用了js的DOM進行元素查找獲得了些許靈感最後實現了這個功能。 1 ...
  • 其他章節請看: react 高效高質量搭建後臺系統 系列 表格 有一種頁面在後臺系統中比較常見:頁面分上下兩部分,上部分是 input、select、時間等查詢項,下部分是查詢項對應的表格數據。包含增刪改查,例如點擊新建進行新增操作。就像這樣: 本篇將對 ant 的表格進行封裝。效果如下: spug ...
  • 問題:對於超大的 string V8不能支持 問題背景 在 Nodejs 計算服務中,對端上上報的記憶體信息二進位數據進行預處理+緩存時,遇到了一個奇怪的報錯:RangeError: Invalid string length 。根據該報錯信息,查找得知是字元串長度超過了 node.js 的限制,即 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...