Optional使用详解

文章详细介绍了Java8中的Optional类,用于防止空指针异常。Optional类提供了of、ofNullable、orElse、orElseGet、map、isPresent、ifPresent和filter等方法,帮助开发者更安全地处理可能为null的对象。通过这些方法,可以更优雅地编写代码,提高程序的健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Optional使用详解


为了防止空指针报错NullPointerException,一我们都会加上if,else,想让代码变得更优雅,JAVA8提供了Optional类来优化这种写法

1.构造函数

构造函数使用private修饰,不能直接被外部访问(没办法new出来),Optional的本质,就是内部储存了一个真实的值,在构造的时候,就直接判断其值是否为空。下面为源码


    /**
     * Constructs an instance with the value present.
     *
     * @param value the non-null value to be present
     * @throws NullPointerException if value is null
     */
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    //requireNonNull()方法
    public static <T> T requireNonNull(T obj) {
        //使用构造函数创建对象,value为null则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

2.Optional.of(T value)

一般推荐使用Optional.ofNullable(T value),在实际生产中很少使用of()方法,因为使用of()方法,value为null时会报出空指针。不过已有一些场景会用到,比如一些需要空指针暴露的接口或测试类中。

作用
  • 当value值为空时,依然会报NullPointerException
  • 当value值不为空时,能正常构造Optional对象。
使用
//1.当 str=null,报空指针
String str = null;
Optional<String> str1 = Optional.of(str);
源码(只想知道怎么用的可以略过)
   public static <T> Optional<T> of(T value) {
        //构造函数创建对象
        return new Optional<>(value);
    }
   //构造函数
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
   //requireNonNull()方法
   public static <T> T requireNonNull(T obj) {
       //若传入的value为null,则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }


    

Optional.ofNullable(T value)

与of(T value)最大的区别就是,value可以为空,推荐使用

作用
  • 当value值为空时,不会报空指针。
  • 当value值不为空时,能正常构造Optional对象。
使用
String str = null;
//str为空时不会报空指针
Optional<String> str2 = Optional.ofNullable(str);
源码
    public static <T> Optional<T> ofNullable(T value) {
        //value为null时,执行empty()方法
        return value == null ? empty() : of(value);
    }

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        //返回EMPTY对象
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
   // EMPTY对象化就是new Optional<>
    private static final Optional<?> EMPTY = new Optional<>();


.orElse(T other)

作用

如果有值则将其返回,否则返回指定的other对象。

  • 传入的值为null时,执行other并返回
  • 传入的值不为null时,执行other,返回传入的值
使用

执行以下代码,控制台输出Hello被执行了,可见,传入的vaule不为null,但是t.rousHello()依然执行。

    public  String rousHello() {
        System.out.println("Hello被执行了");
        return "Hello!!!";
    }  
   public static void main(String[] args) {
         test1 t=new test1();
     
String s = Optional.ofNullable("Str").orElse(t.rousHello());
     
   }
源码
    public T orElse(T other) {
        //value为ofNullable(T vaule)的value,vaule不为空,返回balue,否则执行other
        return value != null ? value : other;
    }

.orElseGet(Supplier<? extends T> other)

比较推荐使用

作用
  • orElse()一定会被执行,而orElseGet()只有传入的参数为null时才会被执行

  • 只有传入的参数为null情况才才会执行orElseGet()内容

使用
   public  String rousHello() {
        System.out.println("Hello被执行了");
        return "Hello!!!";
    }
String s = Optional.ofNullable(str).orElseGet(() -> t.rousHello());
源码
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

.map(Function<? super T, ? extends U> mapper)

作用

不会返回空指针的获取对象属性

使用

//例如User中有个Address属性,Address对象中有详细地址
public String getCity(User user) throws Exception{
    return Optional.ofNullable(user)
                   .map(u-> u.getAddress())
                   .map(a->a.getCity())
                   .orElseThrow(()->new Exception("获取用户地址失败!"));
}
源码
   public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
       //1.为空则报空指针错误(前面讲过)
        Objects.requireNonNull(mapper);
       //不存在,返回EMPTY对象(前面讲过)
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

  //requireNonNull()方法
   public static <T> T requireNonNull(T obj) {
       //若传入的value为null,则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

isPresent()

作用
  • 判断是否存在.不存在返回false,存在返回true
使用
boolean present = Optional.ofNullable(user).isPresent();
源码

源码很容易理解,直接判断value是否!=null

    public boolean isPresent() {
        return value != null;
    }

ifPresent(Consumer<? super T> consumer)

作用
  • 如果存在,则往下走
使用
//如果user存在,则覆盖user的age和name属性       
Optional.ofNullable(user).ifPresent(u->{
            u.setAge(100);
            u.setName("ifPresent");
        });
源码
   public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

filter(Predicate<? super T> predicate)

作用

  • 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。

使用

        user.setName("张四");
        //此处会报空指针,因为get()方法在value为null的情况下会报空指针
        User user1 = Optional.ofNullable(user).filter(
                u -> u.getName() == "张三"
        ).get();

        Optional<User> user2 = Optional.ofNullable(user).filter(
                u -> u.getName() == "张三"
        );
        user2.ifPresent(u->u.setAge(99));

源码

    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值