日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

JAVA8新特性系列我們已經介紹了Stream、Lambda表達式、DateTime日期時間處理,最后以“NullPointerException” 的克星Optional類的講解來收尾。

Java8新特性之空指針異常的克星Optional類

 

背景

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

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

先來看一下不使用Optional類時,我們為了防止NullPointerException會怎么處理。

Java8新特性之空指針異常的克星Optional類

 

為了防止出現異常,需要不停的判斷對象是否為null。但如果業務邏輯比較復雜,會涌現出大量的ifelse。看似邏輯縝密,但易讀性卻并不高。

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

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

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

對照一下代碼,看看神不神奇?!

Optional類簡介

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

public final class Optional<T> {}

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

通過源代碼會發現,它并沒有實現java.io.Serializable接口,因此應避免在類屬性中使用,防止意想不到的問題。

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

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

創建Optional對象

創建Optional對象有三種方法:empty()、of()、ofNullable(),均為靜態方法。

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

Optional empty = Optional.empty();

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

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

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

Optional ofNullOptional = Optional.ofNullable(null);

此時,通過調用其isPresent方法可以查看該Optional中是否值為null。

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

此時如果直接調用get方法獲取值,則會拋出異常。

ofNullOptional.get();

get獲取Optional中的值

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

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

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

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

map獲取Optional中的值

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

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

map方法,如果有值,則對其執行調用映射函數得到返回值。如果返回值不為null,則創建包含映射返回值的Optional作為map方法返回值,否則返回空Optional。

flatMap獲取Optional中的值

如果有值,則返回Optional類型返回值,否則返回空Optional。flatMap與map方法類似。但flatMap中的mApper返回值必須是Optional。調用結束時,flatMap不會對結果用Optional封裝。

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

調用的是當前類OptionalTest的另外一個方法:

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

orElse獲取Optional中的值

orElse方法,如果有值就返回,否則返回一個給定的值作為默認值;

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

上面這種情況就會返回“--”。

在此,這種操作與三目運算效果一樣。

str != null ? str : "--"

上面這種情況就會返回“--”。

在此,這種操作與三目運算效果一樣。

str != null ? str : "--"

orElseGet獲取Optional中的值

orElseGet()方法與orElse()方法作用類似,但生成默認值的方式不同。該方法接受一個Supplier函數式接口參數,用于生成默認值;

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

很顯然,這里可以處理更多的業務邏輯。

orElseThrow獲取Optional中的值

orElseThrow()方法與get()方法類似,當值為null時調用會拋出NullPointerException異常,但該方法可以指定拋出的異常類型。

Optional.empty().orElseThrow(()-> new RuntimeException("請先關注公眾號!"));

此時打印異常信息為:

Optional.empty().orElseThrow(()-> new RuntimeException("請先關注公眾號!"));

判斷并執行操作

ifPresent方法,可對值進行判斷然后打印,接收參數為Consumer函數式接口。

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

當然,也可以在函數中執行其他復雜操作:

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

filter()方法過濾

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

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

使用誤區

關于使用Optional的誤區有以下:

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

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

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

最后,我自己是一名從事了多年開發的JAVA老程序員,今年年初我花了一個月整理了一份最適合2019年學習的java學習干貨,可以送給每一位喜歡java的小伙伴,想要獲取的可以關注我的頭條號并在后臺私信我:java,即可免費獲取。

作者:secbro2

來源:掘金

分享到:
標簽:Java8
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定