欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java/jdk8 Optional如何解决NPE

程序员文章站 2022-06-07 12:36:23
...

一、前言

最早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,考虑默认值等事情。