Optional使用方式

Optional在jdk8中引入,已经有很长时间了,但是对于它的使用在平时的项目中最多只是拿它做下面这样的处理:

XX e = Optional.ofNullable(xx.xx(x.x()))
                        .orElseThrow(() -> new xxException("xxx"));

判断某个方法返回的值是否为null,如果是会抛出一个异常。

在Optional引入之前处理null都是使用if去判断,这样写起来有点繁琐,但是最主要的还是很容易忘记判断值是否为null。使用可能为null的值去执行程序会出现很多意想不到的结果,可能会抛出NPE,可能出现一些其他的问题。为了避免这些问题所以jdk8引入了Optional去处理,当然上面的例子只是很简单的使用,也可以说不是很正确的使用。

在哪用

  • 在可能为空的成员变量的get方法上使用Optional返回

class Student {
        //name可能为null
        private String name;
        //id肯定不会为null
        private Integer id;

        public Student(String name) {
            this.name = name;
        }

        public Optional<String> getName() {
            return Optional.of(name);
        }
        
        public Integer getId(){
            return id;
        }
    }
  • 不要在set方法和构造方法参数上使用Optional接收参数

在set方法和构造函数上如果使用Optional接收参数会使调用这个方法的人很痛苦,因为它需要包装成Optional然后去调用。最好的做法应该是便利胜过对输入的严格要求。

  • 使用Optional作为业务逻辑方法的返回结果

public Optional<Address> getAdderss(){
            //做一些逻辑处理
            return ...//如果找到了地址则返回对应的地址的Optional,如果没有找到则返回Optional.empty()
        }

看本文开头的例子,就是一种不好的返回方式,应该返回一个被Optional包装的值,而不是直接返回真实的值。

 

如何用

拿到了对应的Optional如何来做处理?

optionalStudent.get().getName();

上面的这种方式直接去使用get去获取Optional中的值是有问题,因为当Optional中包装的值是null,还是会抛出异常。

下面换一种方式确保它不为空再使用。

if(optionalStudent.isPresent()){
     optionalStudent.get().getName();
}

上面的那种方式和以前的写法没有什么区别,没有将Optional的功能用好。也同样存在忘记判断是否为null后再去使用。

   Optional<Student> optionalStudent = Optional.ofNullable(new Student(null));
        System.out.println(optionalStudent.map(Student::getName).orElse("xx"));
        System.out.println(optionalStudent.map(Student::getName).orElseThrow(() -> new Exception()));

class Student {
        private String name;

        public Student(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

可以使用上面的方式获取,如果在值为Student的name为null的情况下,或返回一个指定的字符串“xx”。当然也可以抛出异常。

上面的例子是一个对象里的成员变量是null,如果返回的对象就是null呢,上面的程序还是会一样的执行吗,比如:

//这里给定的是null
Optional<Student> optionalStudent = Optional.ofNullable(null);
        System.out.println(optionalStudent.map(Student::getName).orElse("xx"));
        System.out.println(optionalStudent.map(Student::getName).orElseThrow(() -> new Exception()));

这里还是会和上面执行的结果一样。当然也可以使用ifPresent方法,当值不为null时才会执行里面的代码。

optionalStudent.ifPresent(student -> {
        //不为null时才会执行
            System.out.println(student.getName());
        });

参考资料

https://blog.joda.org/2015/08/java-se-8-optional-pragmatic-approach.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 8引入了Optional类,它是一个容器对象,可以包含或者不包含非空值。Optional类主要用于解决空指针异常的问题,它提供了一种优雅的方式来处理可能为空的值。 下面是Java 8 Optional使用方式: 1. 创建Optional对象: - 使用静态方法`Optional.of(value)`创建一个包含非空值的Optional对象。 - 使用静态方法`Optional.empty()`创建一个空的Optional对象。 - 使用静态方法`Optional.ofNullable(value)`创建一个包含可能为空值的Optional对象。 2. 判断Optional对象是否包含值: - 使用`isPresent()`方法判断Optional对象是否包含非空值。 - 使用`isEmpty()`方法判断Optional对象是否为空。 3. 获取Optional对象的值: - 使用`get()`方法获取Optional对象中的值。注意:如果Optional对象为空,调用`get()`方法会抛出NoSuchElementException异常。 4. 处理Optional对象的值: - 使用`ifPresent(Consumer<? super T> consumer)`方法,传入一个Consumer函数式接口来处理Optional对象中的值。如果Optional对象非空,则执行传入的Consumer接口中的逻辑。 - 使用`orElse(T other)`方法,如果Optional对象为空,则返回传入的默认值other。 - 使用`orElseGet(Supplier<? extends T> other)`方法,如果Optional对象为空,则通过传入的Supplier函数式接口生成一个默认值。 - 使用`orElseThrow(Supplier<? extends X> exceptionSupplier)`方法,如果Optional对象为空,则通过传入的Supplier函数式接口抛出一个异常。 5. 使用Optional进行链式调用: - 使用`map(Function<? super T, ? extends U> mapper)`方法,传入一个Function函数式接口来对Optional对象中的值进行转换。 - 使用`flatMap(Function<? super T, Optional<U>> mapper)`方法,传入一个Function函数式接口来对Optional对象中的值进行转换,并返回一个新的Optional对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值