国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Java中Optional的使用指南

Java中Optional的使用指南

2021-08-02 10:36申城異鄉人 Java教程

這篇文章主要給大家介紹了關于Java中Optional使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

提到NullPointerException(簡稱NPE)異常,相信每個Java開發人員都不陌生,從接觸編程的第1天起,它就和我們如影隨形,最近處理的線上bug中,有不少都是對象沒判空導致的NullPointerException異常。

1. 簡單回顧

引起NullPointerException異常的地方有很多,比如調用String的trim()方法,比如對BigDecimal進行計算時,比如將包裝類型轉化為基本類型時,這里簡單回顧下。

假設有個導入模版定義如下:

  1. package com.zwwhnly.springbootaction.model;
  2.  
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5.  
  6. /**
  7. * 導入模版
  8. */
  9. @Data
  10. @AllArgsConstructor
  11. public class ImportTemplate {
  12. /**
  13. * 模版id
  14. */
  15. private int templateId;
  16.  
  17. /**
  18. * 模版名稱
  19. */
  20. private String templateName;
  21.  
  22. /**
  23. * 模版下載url
  24. */
  25. private String url;
  26.  
  27. /**
  28. * 備注
  29. */
  30. private String remark;
  31. }

然后看下如下代碼:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. System.out.println(importTemplate.getUrl());
  4. }
  5.  
  6. public static ImportTemplate getImportTemplateById(int id) {
  7. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  8. }

正常情況下,這段代碼肯定是沒有問題的,但當getImportTemplateById方法返回null時,這段代碼就會拋出NullPointerException異常,如下所示:

  1. public static ImportTemplate getImportTemplateById(int id) {
  2. return null;
  3. }

Java中Optional的使用指南

為了程序能正常運行,就要判斷importTemplate是否為null,所以代碼就修改為了:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. if (importTemplate != null) {
  4. System.out.println(importTemplate.getUrl());
  5. }
  6. }

項目中類似的判空代碼應該有很多,大家可以自行看下自己項目的代碼。

2. 使用Optional

為了避免NullPointerException異常,JDK1.8新增了Optional類來處理空指針異常,該類位于java.util包下,提供了一系列方法,

并且可以配合Lambda表達式一起使用,使代碼看起來更加清晰,接下來我們看下它的使用方法。

2.1 創建實例

創建Optional實例有以下3種方式,分別為:

調用empty方法

  1. Optional<ImportTemplate> optionalImportTemplate = Optional.empty();

調用of方法

  1. ImportTemplate importTemplate = new ImportTemplate(1, "銷售訂單-普通商品導入模版",
  2. "o_w-140e3c1f41c94f238196539558e25bf7", null);
  3. Optional<ImportTemplate> optionalImportTemplate = Optional.of(importTemplate);

調用ofNullable方法(推薦)

  1. ImportTemplate importTemplate = new ImportTemplate(1, "銷售訂單-普通商品導入模版",
  2. "o_w-140e3c1f41c94f238196539558e25bf7", null);
  3. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(importTemplate);

值得注意的是,當參數為null時,調用of方法會拋NullPointerException異常,但調用ofNullable方法不會(更符合使用場景),因此推薦使用ofNullable方法:

  1. ImportTemplate importTemplate = null;
  2. Optional<ImportTemplate> optionalImportTemplate = Optional.of(importTemplate);

Java中Optional的使用指南

2.2 判斷是否有值

可以調用isPresent方法來判斷對象是否有值(不為null),使用方法如下所示:

  1. ImportTemplate importTemplate = null;
  2. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(importTemplate);
  3.  
  4. System.out.println(optionalImportTemplate.isPresent());

以上代碼的輸出結果為:

Java中Optional的使用指南

  1. ImportTemplate importTemplate = new ImportTemplate(1, "銷售訂單-普通商品導入模版",
  2. "o_w-140e3c1f41c94f238196539558e25bf7", null);
  3. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(importTemplate);
  4.  
  5. System.out.println(optionalImportTemplate.isPresent());

以上代碼的輸出結果為:

Java中Optional的使用指南

看下isPresent的源碼,邏輯非常簡單,就是判斷了我們傳入的對象是否有值,即不為null:

  1. /**
  2. * Return {@code true} if there is a value present, otherwise {@code false}.
  3. *
  4. * @return {@code true} if there is a value present, otherwise {@code false}
  5. */
  6. public boolean isPresent() {
  7. return value != null;
  8. }

2.3 獲取值

可以調用get方法來獲取對象的有值,使用方法如下所示:

  1. ImportTemplate importTemplate = new ImportTemplate(1, "銷售訂單-普通商品導入模版",
  2. "o_w-140e3c1f41c94f238196539558e25bf7", null);
  3. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(importTemplate);
  4. System.out.println(optionalImportTemplate.get());

以上代碼的輸出結果為:

Java中Optional的使用指南

值得注意的是,當我們傳入的對象為null時,調用get方法會拋出java.util.NoSuchElementException異常,而不是返回null。

  1. ImportTemplate importTemplate = null;
  2. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(importTemplate);
  3. System.out.println(optionalImportTemplate.get());

以上代碼的輸出結果為:

Java中Optional的使用指南

看下get方法的源碼,就可以知道原因:

  1. public T get() {
  2. if (value == null) {
  3. throw new NoSuchElementException("No value present");
  4. }
  5. return value;
  6. }

2.4 先用isPresent,再用get(不推薦)

然后我們回顧下文初的代碼:

  1. ImportTemplate importTemplate = getImportTemplateById(1);
  2. if (importTemplate != null) {
  3. System.out.println(importTemplate.getUrl());
  4. }

可能很多同學會把代碼優化為下面這樣的寫法:

  1. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(getImportTemplateById(1));
  2. if (optionalImportTemplate.isPresent()) {
  3. System.out.println(optionalImportTemplate.get().getUrl());
  4. }

不推薦這么使用,因為判斷的地方沒減少,而且還不如原來看起來清晰。

2.5 ifPresent(推薦)

那該怎么優化呢?答案就是使用ifPresent方法,該方法接收一個Consumer類型的參數,當值不為null時,就執行,當值為null時,就不執行,源碼如下所示:

  1. public void ifPresent(Consumer<? super T> consumer) {
  2. if (value != null)
  3. consumer.accept(value);
  4. }

優化之后的代碼如下所示:

  1. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(getImportTemplateById(1));
  2. optionalImportTemplate.ifPresent(importTemplate -> System.out.println(importTemplate.getUrl()));

當然,也可以寫更多的邏輯:

  1. Optional<ImportTemplate> optionalImportTemplate = Optional.ofNullable(getImportTemplateById(1));
  2. optionalImportTemplate.ifPresent(importTemplate -> {
  3. System.out.println(importTemplate.getTemplateId());
  4. System.out.println(importTemplate.getTemplateName());
  5. System.out.println(importTemplate.getUrl());
  6. System.out.println(importTemplate.getRemark());
  7. });

2.6 自定義默認值

Optional類提供了以下2個方法來自定義默認值,用于當對象為null時,返回自定義的對象:

  • orElse
  • orElseGet

先來看下orElse方法的使用:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = null;
  3. ImportTemplate firstImportTemplate = Optional.ofNullable(importTemplate)
  4. .orElse(getDefaultTemplate());
  5. System.out.println(firstImportTemplate);
  6.  
  7. importTemplate = new ImportTemplate(2, "銷售訂單-不定規格商品導入模版", "o_w-a7109db89f8d4508b4c6202889a1a2c1", null);
  8.  
  9. ImportTemplate secondImportTemplate = Optional.ofNullable(importTemplate)
  10. .orElse(getDefaultTemplate());
  11. System.out.println(secondImportTemplate);
  12. }
  13.  
  14. public static ImportTemplate getDefaultTemplate() {
  15. System.out.println("getDefaultTemplate");
  16. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  17. }

輸出結果:

Java中Optional的使用指南

再來看下orElseGet方法的使用:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = null;
  3. ImportTemplate firstImportTemplate = Optional.ofNullable(importTemplate)
  4. .orElseGet(() -> getDefaultTemplate());
  5. System.out.println(firstImportTemplate);
  6.  
  7. importTemplate = new ImportTemplate(2, "銷售訂單-不定規格商品導入模版", "o_w-a7109db89f8d4508b4c6202889a1a2c1", null);
  8.  
  9. ImportTemplate secondImportTemplate = Optional.ofNullable(importTemplate)
  10. .orElseGet(() -> getDefaultTemplate());
  11. System.out.println(secondImportTemplate);
  12. }
  13.  
  14. public static ImportTemplate getDefaultTemplate() {
  15. System.out.println("getDefaultTemplate");
  16. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  17. }

輸出結果:

Java中Optional的使用指南

從輸出結果看,2個方法好像差不多,第1次調用都返回了默認模版,第2次調用都返回了傳入的模版,但其實仔細觀察,你會發現當使用

orElse方法時,getDefaultTemplate方法執行了2次,但調用orElseGet方法時,getDefaultTemplate方法只執行了2次(只在第1次傳入模版為null時執行了)。

為什么會這樣呢?帶著這個疑問,我們看下這2個方法的源碼,其中orElse方法的源碼如下所示:

  1. public T orElse(T other) {
  2. return value != null ? value : other;
  3. }

可以看到,參數other是個對象,這個參數肯定是要傳的,但只有value為空時,才會用到(返回)這個對象。

orElseGet方法的源碼如下所示:

  1. public T orElseGet(Supplier<? extends T> other) {
  2. return value != null ? value : other.get();
  3. }

可以看到,參數other并不是直接傳入對象,如果value為null,才會執行傳入的參數獲取對象,如果不為null,直接返回value。

2.7 自定義異常

Optional類提供了orElseThrow方法,用于當傳入的對象為null時,拋出自定義的異常,使用方法如下所示:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = new ImportTemplate(2, "銷售訂單-不定規格商品導入模版", "o_w-a7109db89f8d4508b4c6202889a1a2c1", null);
  3. ImportTemplate firstImportTemplate = Optional.ofNullable(importTemplate)
  4. .orElseThrow(() -> new IndexOutOfBoundsException());
  5. System.out.println(firstImportTemplate);
  6.  
  7. importTemplate = null;
  8.  
  9. ImportTemplate secondImportTemplate = Optional.ofNullable(importTemplate)
  10. .orElseThrow(() -> new IndexOutOfBoundsException());
  11. System.out.println(secondImportTemplate);
  12. }

輸出結果:

Java中Optional的使用指南

2.8 過濾數據

Optional類提供了filter方法來過濾數據,該方法接收一個Predicate參數,返回匹配條件的數據,如果不匹配條件,返回一個空的Optional,使用方法如下所示:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. Optional<ImportTemplate> filterById = Optional.ofNullable(importTemplate)
  4. .filter(f -> f.getTemplateId() == 1);
  5. System.out.println(filterById.isPresent());
  6.  
  7. Optional<ImportTemplate> filterByName = Optional.ofNullable(importTemplate)
  8. .filter(f -> f.getTemplateName().contains("發貨單"));
  9. System.out.println(filterByName.isPresent());
  10. }
  11.  
  12. public static ImportTemplate getImportTemplateById(int id) {
  13. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  14. }

輸出結果:

Java中Optional的使用指南

2.9 轉換值

Optional類提供了以下2個方法來轉換值:

  • map
  • flatMap

map方法的使用方法如下所示:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. Optional<String> optionalUrl = Optional.ofNullable(importTemplate)
  4. .map(f -> "url:" + f.getUrl());
  5. System.out.println(optionalUrl.isPresent());
  6. System.out.println(optionalUrl.get());
  7. }
  8.  
  9. public static ImportTemplate getImportTemplateById(int id) {
  10. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  11. }

輸出結果:

Java中Optional的使用指南

flatMap方法和map方法類似,不過它支持傳入Optional,使用方法如下所示:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. Optional<String> optionalUrl = Optional.ofNullable(importTemplate)
  4. .flatMap(f -> Optional.ofNullable(f.getUrl()));
  5. System.out.println(optionalUrl.isPresent());
  6. System.out.println(optionalUrl.get());
  7. }
  8.  
  9. public static ImportTemplate getImportTemplateById(int id) {
  10. return new ImportTemplate(1, "銷售訂單-普通商品導入模版", "o_w-140e3c1f41c94f238196539558e25bf7", null);
  11. }

輸出結果:

Java中Optional的使用指南

3. 總結

對于程序員來說,一不注意就會出現NullPointerException異常,避免它的方式也很簡單,比如使用前判斷不能為空:

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. if (importTemplate != null) {
  4. System.out.println(importTemplate.getUrl());
  5. }
  6. }

比如為空時,直接返回(或者返回默認值):

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = getImportTemplateById(1);
  3. if (importTemplate == null) {
  4. return;
  5. }
  6. System.out.println(importTemplate.getUrl());
  7. }

比如,使用本文中的Optional。

使用哪種方式不重要,盡可能地避免NullPointerException異常才重要。

4. 參考

理解、學習與使用 Java 中的 Optional

總結

到此這篇關于Java中Optional使用的文章就介紹到這了,更多相關Java Optional使用內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/zwwhnly/p/14341931.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲综合精品久久 | 久久久久久久成人 | 日韩高清三区 | 国产精品五区 | 久久免费99精品久久久久久 | 一区二区三区在线播放 | 免费av电影网站 | 亚洲成人av一区二区三区 | 夜夜av| 日本久久久 | 久久精品久久久 | 黄色免费网站在线观看 | 日韩一区二区三区在线 | 日韩在线免费 | 91成人小视频 | 日韩欧美在线免费观看 | 中文字幕天堂在线 | 日韩免费 | 激情自拍偷拍 | 欧美一区二区三区久久精品 | 四虎免费紧急入口观看 | 久久久久久久久99精品 | 亚洲综合中文网 | 国产美女视频自拍 | 久久久久999 | 狠狠艹夜夜艹 | 一级片黄 | 欧美狠狠操| 精品久久av | 一区二区福利 | 国产一区二区三区在线看 | 国产日韩欧美一二三区 | 色成人免费网站 | 日韩毛片免费在线观看 | 国产精品久久久久久久久 | 日韩成人免费 | 欧美影院| 亚洲精品视频在线观看免费 | 国产成人黄色av | 久久蜜桃精品一区二区三区综合网 | 国产美女福利在线 |