<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Optional 類解決空指針異常

          共 6176字,需瀏覽 13分鐘

           ·

          2021-05-05 11:19

          前言

          空指針異常是導(dǎo)致 Java 應(yīng)用程序失敗的最常見原因。以前,為了解決空指針異常,Google 公司著名的 Guava 項目引入了 Optional 類,Guava 通過使用檢查空值的方式來防止代碼污染,它鼓勵程序員寫更干凈的代碼。受到 Google Guava 的啟發(fā),Optional 類已經(jīng)成為 Java8 類庫的一部分。Optional 實際上是個容器:它可以保存類型 T 的值,或者僅僅保存 null。Optional 提供很多有用的方法,這樣我們就不用顯式進(jìn)行空值檢測。

          Optional 范例

          構(gòu)造方式

          Optional 的三種構(gòu)造方式:Optional.of(obj),Optional.ofNullable(obj) 和 Optional.empty()。

          • Optional.of(),依據(jù)一個非空值創(chuàng)建 Optional

          // 如果 car 是一個 null, 這段代碼會立即拋出 
          // NullPointException, 而不是等到試圖訪問 car 的屬性值時才返回一個錯誤.
          Optional<Integer> optCar = Optional.of(car);
          • Optional.ofNullable(),可接受 null 的 Optional(實現(xiàn)序列化的域模型時使用)

          // 創(chuàng)建一個允許 null 值的 Optional 對象, 
          // 如果 car 是 null, 那么得到的 Optional 對象就是個空對象.
          Optional<Integer> optCar = Optional.ofNullable(car);
          • Optional.empty(),所有 null 包裝成的 Optional 對象。

          // 聲明一個空的 Optional
          Optional<Integer> empty = Optional.empty();

          isPresent()/ifPresent(Consumer consumer)

          isPresent(),判斷值是否存在。

          Optional<Integer> optional1 = Optional.ofNullable(1);
          Optional<Integer> optional2 = Optional.ofNullable(null);

          // isPresent 判斷值是否存在
          System.out.println(optional1.isPresent() == true);
          System.out.println(optional2.isPresent() == false);

          ifPresent(Consumer consumer):如果 option 對象保存的值不是 null,則調(diào)用 consumer 對象,否則不調(diào)用。

          // 如果不是 null, 調(diào)用 Consumer; 如果 null, 不調(diào)用 Consumer
          optional1.ifPresent(new Consumer<Integer>() {
              @Override
              public void accept(Integer t
          {
                  System.out.println("value is" + t);
              }
          });

          // Lambda 表達(dá)式寫法
          optional1.ifPresent(t -> System.out.println("value is" + t));

          orElse(value)/orElseGet(Supplier supplier)

          orElse(value):如果 optional 對象保存的值不是 null,則返回原來的值,否則返回 value。

          Optional<Integer> optional1 = Optional.ofNullable(1);
          Optional<Integer> optional2 = Optional.ofNullable(null);

          System.out.println(optional1.orElse(1000) == 1);// true
          System.out.println(optional2.orElse(1000) == 1000);// true

          orElseGet(Supplier supplier):功能與 orElse 一樣,只不過 orElseGet 參數(shù)是一個對象,即無則由函數(shù)來產(chǎn)生。

          Optional<Integer> optional1 = Optional.ofNullable(1);
          Optional<Integer> optional2 = Optional.ofNullable(null);

          System.out.println(optional1.orElseGet(() -> {
              return 1000;
          }) == 1);
          // true

          System.out.println(optional2.orElseGet(() -> {
              return 1000;
          }) == 1000);
          // true

          orElseThrow()

          orElseThrow():值不存在則拋出異常,存在則什么不做,有點類似 Guava 的 Precoditions。

          Optional<Integer> optional = Optional.ofNullable(null);

          optional.orElseThrow(() -> {
              throw new NullPointerException();
          });

          filter(Predicate)

          filter(Predicate):判斷 Optional 對象中保存的值是否滿足 Predicate,并返回新的 Optional。

          Optional<Integeroptional = Optional.ofNullable(1);

          Optional<Integer> filter = optional.filter((a) -> a == 1);

          map(Function)/flatMap(Function)

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

          Optional<String> upperName = name.map((value) -> value.toUpperCase());
          System.out.println(upperName.orElse("No value found"));

          flatMap(Function) 如果有值,為其執(zhí)行 mapping 函數(shù)返回 Optional 類型返回值,否則返回空 Optional。flatMap 與 map(Funtion)方法類似,區(qū)別在于 flatMap 中的 mapper 返回值必須是 Optional。調(diào)用結(jié)束時,flatMap 不會對結(jié)果用 Optional 封裝。[P.S. 參考博文 [3]:Cascading Optional Objects Using the flatMap Method]

          upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
          System.out.println(upperName.orElse("No value found"));

          Optional 類的鏈?zhǔn)椒椒?/span>

          錯誤示范 / 正確示范

          • 示范(一)

          // ** 錯誤示范
          Optional<User> user = ...... 
          if (user.isPresent()) {
              return user.getOrders();
          else {
              return Collections.emptyList();
          }
          // 二者實質(zhì)上是沒有任何分別
          User user = .....
          if (user != null) {
              return user.getOrders();
          else {
              return Collections.emptyList();
          }

          // ** 正確示范
          return user.map(u -> u.getOrders()).orElse(Collections.emptyList())

          // map 是可能無限級聯(lián)的, 比如再深一層, 獲得用戶名的大寫形式
          return user.map(u -> u.getUsername())
                     .map(name -> name.toUpperCase())
                     .orElse(null);
          • 示范(二)

          // ** 錯誤示范
          String version = "UNKNOWN";
          if(computer != null){
            Soundcard soundcard = computer.getSoundcard();
            if(soundcard != null){
              USB usb = soundcard.getUSB();
              if(usb != null){
                version = usb.getVersion();
              }
            }
          }

          // ** 正確示范
          String version = computer.map(Computer::getSoundcard)
                            .map(Soundcard::getUSB)
                            .map(USB::getVersion)
                            .orElse("UNKNOWN");

          參考博文

          [1]. Java 8 Optional 類深度解析
          [2]. 使用 Java8 Optional 的正確姿勢
          [3]. Tired of Null Pointer Exceptions? Consider Using Java SE 8’s Optional!

          source:https://morning-pro.github.io/archives/8eb6feba.html

          喜歡,在看

          瀏覽 31
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级a一级a爰片免费 | 一区一区视频 | 久久久91精品国产一区苍井空 | 美女特黄A级 | 围产精品久久久久久久久久久久 |