最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8新特性之空指針異常的克星Optional類的實(shí)現(xiàn)

 更新時(shí)間:2019年10月23日 15:30:21   作者:二師兄-公眾號(hào)-程序新視界  
這篇文章主要介紹了Java8新特性之空指針異常的克星Optional類的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Java8新特性系列我們已經(jīng)介紹了Stream、Lambda表達(dá)式、DateTime日期時(shí)間處理,最后以“NullPointerException” 的克星Optional類的講解來收尾。

背景

作為開發(fā)人員每天與NullPointerException斗智斗勇。每接收到參數(shù)或調(diào)用方法獲得值得判斷一下是否為null。稍不留意,空指針異常就像幽靈一樣出現(xiàn)了。

這篇文章我們來學(xué)習(xí)Java8是如何通過Optional類來避免空指針異常的。

先來看一下不使用Optional類時(shí),我們?yōu)榱朔乐筃ullPointerException會(huì)怎么處理。

public String getParentName(Person son) {
 if (son != null) {
 Person parent = son.getParent();
 if (parent != null) {
  return parent.getUsername();
 } else {
  return "--";
 }
 }

 return "--";
}

為了防止出現(xiàn)異常,需要不停的判斷對(duì)象是否為null。但如果業(yè)務(wù)邏輯比較復(fù)雜,會(huì)涌現(xiàn)出大量的ifelse??此七壿嬁b密,但易讀性卻并不高。

為了解決相關(guān)問題,在Effective Java中建議若方法返回類型為集合,則通過返回空集合以避免 NullPointerException,真是煞費(fèi)苦心。

先看一下上面的代碼使用Optional之后會(huì)變成什么樣子。

public String getParentNameWithOptional(Person son) {
 return Optional.ofNullable(son).map(Person::getParent).map(Person::getUsername).orElse("--");
}

對(duì)照一下代碼,看看神不神奇?!

Optional類簡(jiǎn)介

java.util.Optional類的引入很好的解決空指針異常,類聲明如下:

public final class Optional<T> {}

java.util.Optional類是一個(gè)封裝了Optional值的容器對(duì)象,Optional值可以為null,如果值存在,調(diào)用isPresent()方法返回true,調(diào)用get()方法可以獲取值。

通過源代碼會(huì)發(fā)現(xiàn),它并沒有實(shí)現(xiàn)java.io.Serializable接口,因此應(yīng)避免在類屬性中使用,防止意想不到的問題。

除了Optional類之外,還擴(kuò)展了一些常用類型的Optional對(duì)象,比如:OptionalDouble、OptionalInt、OptionalLong。用法基本上相似。

下面通過具體的操作和功能來了解Optional類。

創(chuàng)建Optional對(duì)象

創(chuàng)建Optional對(duì)象有三種方法:empty()、of()、ofNullable(),均為靜態(tài)方法。

如果Optional對(duì)象沒有值則用empty()方法。

Optional empty = Optional.empty();

如果確定Optional對(duì)象的值不為null,則可用of()方法。

Optional stringOptional = Optional.of("Hello 公眾號(hào):程序新視界");

如果不確定Optional對(duì)象的值是否為null,則可用ofNullable()。比如上面,不確定Person對(duì)象是不否null,就用了ofNullable()方法。當(dāng)然,也可以直接給該方法傳null。

Optional ofNullOptional = Optional.ofNullable(null);

此時(shí),通過調(diào)用其isPresent方法可以查看該Optional中是否值為null。

boolean bool = ofNullOptional.isPresent();
System.out.println(bool);

此時(shí)如果直接調(diào)用get方法獲取值,則會(huì)拋出異常。

ofNullOptional.get();

get獲取Optional中的值

通過get方法可獲取Optional中的值,但如果值為null,則會(huì)拋出異常。

Optional ofNullOptional = Optional.ofNullable(null);
ofNullOptional.get();

異常信息:

java.util.NoSuchElementException: No value present
  at java.util.Optional.get(Optional.java:135)
...

此時(shí),需要另外一個(gè)方法的輔助:isPresent()。該方法可判定Optional中是否有值,如果有則返回true,如果沒有則返回false。

Optional ofNullOptional = Optional.ofNullable(null);
boolean bool = ofNullOptional.isPresent();
if(bool){
 ofNullOptional.get();
}

map獲取Optional中的值

對(duì)于對(duì)象操作,也可以通過map來獲取值,最開始簡(jiǎn)化的例子就是如此。

Optional<Person> sonOptional = Optional.ofNullable(son);
System.out.println(sonOptional.map(Person::getUsername));

map方法,如果有值,則對(duì)其執(zhí)行調(diào)用映射函數(shù)得到返回值。如果返回值不為null,則創(chuàng)建包含映射返回值的Optional作為map方法返回值,否則返回空Optional。

flatMap獲取Optional中的值

如果有值,則返回Optional類型返回值,否則返回空Optional。flatMap與map方法類似。但flatMap中的mapper返回值必須是Optional。調(diào)用結(jié)束時(shí),flatMap不會(huì)對(duì)結(jié)果用Optional封裝。

Optional<Person> sonOptional = Optional.ofNullable(son);
sonOptional.flatMap(OptionalTest::getOptionalPerson);

調(diào)用的是當(dāng)前類OptionalTest的另外一個(gè)方法:

public static Optional<Person> getOptionalPerson(Person person){
 return Optional.ofNullable(person);
}
 

orElse獲取Optional中的值

orElse方法,如果有值就返回,否則返回一個(gè)給定的值作為默認(rèn)值;

Optional.empty().orElse("--");

上面這種情況就會(huì)返回“–”。

在此,這種操作與三目運(yùn)算效果一樣。

str != null ? str : "--"

orElseGet獲取Optional中的值

orElseGet()方法與orElse()方法作用類似,但生成默認(rèn)值的方式不同。該方法接受一個(gè)Supplier<? extends T>函數(shù)式接口參數(shù),用于生成默認(rèn)值;

Optional.empty().orElseGet(() -> {
  String a = "關(guān)注";
  String b = "公眾號(hào):程序新視界";
  return a  b;
 });

很顯然,這里可以處理更多的業(yè)務(wù)邏輯。

orElseThrow獲取Optional中的值

orElseThrow()方法與get()方法類似,當(dāng)值為null時(shí)調(diào)用會(huì)拋出NullPointerException異常,但該方法可以指定拋出的異常類型。

Optional.empty().orElseThrow(()-> new RuntimeException("請(qǐng)先關(guān)注公眾號(hào)!"));

此時(shí)打印異常信息為:

Optional.empty().orElseThrow(()-> new RuntimeException("請(qǐng)先關(guān)注公眾號(hào)!"));

判斷并執(zhí)行操作

ifPresent方法,可對(duì)值進(jìn)行判斷然后打印,接收參數(shù)為Consumer<? super T>函數(shù)式接口。

Optional.of("公眾號(hào):程序新視界").ifPresent(System.out::println);

當(dāng)然,也可以在函數(shù)中執(zhí)行其他復(fù)雜操作:

Optional.of("公眾號(hào):程序新視界").ifPresent((val)->{
  System.out.println("歡迎關(guān)注"  val);
 });

filter()方法過濾

filter()方法可用于判斷Optional對(duì)象是否滿足給定條件,一般用于條件過濾:

Optional.of("公眾號(hào):程序新視界").filter((val)->{
 return val.contains("程序新視界");
});
// 簡(jiǎn)化寫法
Optional.of("公眾號(hào):程序新視界").filter((val)-> val.contains("程序新視界"));

使用誤區(qū)

關(guān)于使用Optional的誤區(qū)有以下:

  • 正確的使用創(chuàng)建方法,不確定是否為null時(shí)盡量選擇ofNullable方法。
  • 避免用在成員變量上(原因上面已經(jīng)提到);
  • 避免直接調(diào)用Optional對(duì)象的get和isPresent方法;

最后一條可能難理解,試想一下如果先用isPresent方法獲得是否存在,然后決定是否調(diào)用get方法和之前的ifelse判斷并無二致。

Java8提倡函數(shù)式編程,新增的許多API都可以用函數(shù)式編程表示,Optional類也是其中之一。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA?拷貝文件的幾種方式小結(jié)

    JAVA?拷貝文件的幾種方式小結(jié)

    本文主要介紹了JAVA拷貝文件的幾種方式,包含普通拷貝,mmap內(nèi)存映射的方式拷貝,零拷貝sendFile方式實(shí)現(xiàn)和多線程的方式實(shí)現(xiàn)拷貝,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Maven依賴沖突的成因與解決方案

    Maven依賴沖突的成因與解決方案

    在?Java?企業(yè)級(jí)開發(fā)中,依賴管理是每個(gè)開發(fā)者繞不開的核心課題,隨著項(xiàng)目規(guī)模擴(kuò)大、模塊增多、第三方庫引入頻繁,JAR?包版本沖突幾乎成為家常便飯,本文將深入剖析?Maven?依賴沖突的成因、表現(xiàn)形式及排查方法,需要的朋友可以參考下
    2025-12-12
  • springboot 單文件上傳的實(shí)現(xiàn)步驟

    springboot 單文件上傳的實(shí)現(xiàn)步驟

    這篇文章主要介紹了springboot實(shí)現(xiàn)單文件上傳的方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2021-02-02
  • 解決JTable排序問題的方法詳解

    解決JTable排序問題的方法詳解

    本篇文章是對(duì)JTable排序問題的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫

    Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫的具體步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java死鎖問題詳解及示例

    Java死鎖問題詳解及示例

    本文將討論Java程序中死鎖問題的概念、產(chǎn)生原因以及避免策略。同時(shí),我們還將通過代碼示例來進(jìn)一步闡述這個(gè)問題,感興趣的小伙伴可以跟著小編一起來學(xué)習(xí)
    2023-04-04
  • Java內(nèi)存劃分:運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    Java內(nèi)存劃分:運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    聽說Java運(yùn)行時(shí)環(huán)境的內(nèi)存劃分是挺進(jìn)BAT的必經(jīng)之路,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存劃分)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • SpringBoot整合JWT(JSON?Web?Token)生成token與驗(yàn)證的流程及示例

    SpringBoot整合JWT(JSON?Web?Token)生成token與驗(yàn)證的流程及示例

    JSON Web Token(JWT)是一種開放的標(biāo)準(zhǔn)(RFC 7519),定義了一種緊湊的、自包含的方式來安全地在各方之間傳輸信息作為JSON對(duì)象,這篇文章主要給大家介紹了關(guān)于SpringBoot整合JWT(JSON?Web?Token)生成token與驗(yàn)證的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • java中拼接字符串的5種方法效率對(duì)比

    java中拼接字符串的5種方法效率對(duì)比

    這篇文章主要給大家介紹了關(guān)于java中拼接字符串的5種方法效率對(duì)比的相關(guān)資料,文中通過示例代碼和圖片介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • java普通類調(diào)用mapper或者service方法詳解

    java普通類調(diào)用mapper或者service方法詳解

    本文介紹了兩種調(diào)用或獲取Spring Bean的方法:一種是直接使用Test.select(1);另一種是通過自定義SpringUtil工具類實(shí)現(xiàn)對(duì)Spring Bean的獲取和管理,從而簡(jiǎn)化在項(xiàng)目中的Bean調(diào)用流程
    2025-10-10

最新評(píng)論

古交市| 静乐县| 霍州市| 云阳县| 富裕县| 长子县| 枝江市| 宜昌市| 临潭县| 陇川县| 铜陵市| 昌黎县| 卓尼县| 肃宁县| 曲阜市| 海淀区| 义马市| 和田县| 兖州市| 西丰县| 榕江县| 玛纳斯县| 梁河县| 水城县| 青河县| 肃南| 肃北| 东山县| 常山县| 汶上县| 乌拉特前旗| 南陵县| 隆林| 浦北县| 玉环县| 德江县| 准格尔旗| 五常市| 梅州市| 屏东市| 弋阳县|