激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

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

Java中Optional的使用指南

2021-08-02 10:36申城異鄉(xiāng)人 Java教程

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

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

1. 簡單回顧

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

假設(shè)有個導入模版定義如下:

  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 創(chuàng)建實例

創(chuàng)建Optional實例有以下3種方式,分別為:

調(diào)用empty方法

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

調(diào)用of方法

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

調(diào)用ofNullable方法(推薦)

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

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

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

Java中Optional的使用指南

2.2 判斷是否有值

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

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

以上代碼的輸出結(jié)果為:

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());

以上代碼的輸出結(jié)果為:

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 獲取值

可以調(diào)用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());

以上代碼的輸出結(jié)果為:

Java中Optional的使用指南

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

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

以上代碼的輸出結(jié)果為:

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. }

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

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

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

2.5 ifPresent(推薦)

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

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

優(yōu)化之后的代碼如下所示:

  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, "銷售訂單-不定規(guī)格商品導入模版", "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. }

輸出結(jié)果:

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, "銷售訂單-不定規(guī)格商品導入模版", "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. }

輸出結(jié)果:

Java中Optional的使用指南

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

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

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

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

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

orElseGet方法的源碼如下所示:

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

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

2.7 自定義異常

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

  1. public static void main(String[] args) {
  2. ImportTemplate importTemplate = new ImportTemplate(2, "銷售訂單-不定規(guī)格商品導入模版", "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. }

輸出結(jié)果:

Java中Optional的使用指南

2.8 過濾數(shù)據(jù)

Optional類提供了filter方法來過濾數(shù)據(jù),該方法接收一個Predicate參數(shù),返回匹配條件的數(shù)據(jù),如果不匹配條件,返回一個空的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("發(fā)貨單"));
  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. }

輸出結(jié)果:

Java中Optional的使用指南

2.9 轉(zhuǎn)換值

Optional類提供了以下2個方法來轉(zhuǎn)換值:

  • 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. }

輸出結(jié)果:

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. }

輸出結(jié)果:

Java中Optional的使用指南

3. 總結(jié)

對于程序員來說,一不注意就會出現(xiàn)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

總結(jié)

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 九九精品在线观看视频 | 一级美女大片 | 色婷婷综合久色aⅴ | 看91| 国产精品av久久久久久久久久 | 国产1区2区3区中文字幕 | 国产一区二区三区视频免费 | 91久久99热青草国产 | 91美女视频在线观看 | 外国一级黄色片 | 精品国产一区二区三区蜜殿 | 久久久青 | 草久影视| 欧美人与性禽动交精品 | 毛片视频网址 | 自拍偷拍999 | 777zyz色资源站在线观看 | 草久在线 | 91久久国产露脸精品免费 | 国产九色视频在线观看 | 一级国产精品一级国产精品片 | 黄色伊人网站 | 亚洲电影在线观看高清免费 | 国产精品无码久久久久 | 得得啪在线视频 | 中文字幕 亚洲一区 | 看片一区| 精品一区二区在线观看视频 | 亚洲成人伊人 | 一级在线视频 | 成人偷拍片视频在线观看 | 国产精品久久77777 | 在线中文字幕不卡 | 在线中文字幕网站 | 亚洲一区二区 | 欧美日韩大片在线观看 | 国产亚洲精品成人a | 久草手机在线 | 网站一区| 久久久精品99 | 成人三区四区 |