1. 程式人生 > 實用技巧 >Java/jdk8 Optional如何解決NPE

Java/jdk8 Optional如何解決NPE

一、前言

最早optional是google guava工具集中的,後面jdk也把optional收錄了,阿里的java開發手冊裡也說了使用optional解決NPE問題,我們來看看optional是如何解決NPE的。

引入optional目的

"引入Optional並不是要消除每一個null引用,而是幫助設計更普適的API,看見簽名就能瞭解是否接受一個Optional的值,這種強制會讓你更積極地將變數從Optional中解包出來,直面缺失的變數值"

二、optional核心方法

以下是optional相關方法及說明

  • Optional.of傳入的值存在,返回包含該值的Optional物件,否則就丟擲NullPointerException異常
  • Optional.ofNullable傳入的值存在,返回包含該值的Optional物件,否則返回一個空的Optional物件
  • Optional.ifPresent如果值存在就對該值執行傳入的方法,否則就什麼也不做
  • Optional.orElse如果值存在就將其值返回,否則返回傳入的預設值
  • Optional.map如果值存在,就對該值執行提供的mapping函式呼叫,將mapping函式返回值用Optional封裝並返回

三、相關示例

以下是幾個簡單的使用:

//ofNullable 構建optional物件
Optional<User> optUser = Optional.ofNullable(user);
//使用1 判斷是否存在
optUser.ifPresent() 返回 boolean 
//使用2 存在返回,不存在設定預設值
optUser.orElse(null) 
//使用3 取物件屬性值
Optional<String> name = optUser.map(User::getName);       
Optional<String> name = optUser.map(u->u.getName());    

看下正常的使用

if(optUser.ifPresent()){
   name = optUser.get().getName();
}

好像與原本的user!=null程式碼量與效果差不多,的確差不多

public class Java8Tester {
   public static void main(String args[]){
   
      Java8Tester java8Tester = new Java8Tester();
      Integer value1 = null;
      Integer value2 = new Integer(10);
        
      // Optional.ofNullable - 允許傳遞為 null 引數
      Optional<Integer> a = Optional.ofNullable(value1);
        
      // Optional.of - 如果傳遞的引數是 null,丟擲異常 NullPointerException
      Optional<Integer> b = Optional.of(value2);
      System.out.println(java8Tester.sum(a,b));
   }
    
   public Integer sum(Optional<Integer> a, Optional<Integer> b){
    
      // Optional.isPresent - 判斷值是否存在
        
      System.out.println("第一個引數值存在: " + a.isPresent());
      System.out.println("第二個引數值存在: " + b.isPresent());
        
      // Optional.orElse - 如果值存在,返回它,否則返回預設值
      Integer value1 = a.orElse(new Integer(0));
        
      //Optional.get - 獲取值,值需要存在
      Integer value2 = b.get();
      return value1 + value2;
   }
}

可以看到 Integer sum(Optional<Integer> a, Optional<Integer> b)

使用Optional<Integer>包裝類宣告變數,這樣可以醒目的表明了這裡的變數會有NPE,考慮預設值等事情。