您的位置:

Java Optional类简介

在Java中,我们经常会遇到传递参数或返回值可能为空的情况,这就需要使用Optional类。Optional类是Java 8中引入的一个新特性,它可以明确告诉开发者某个方法或变量可能是空值(null),并提供了一些方法来避免空指针错误。

一、Optional类的背景

在Java中,我们经常会遇到某些变量或者方法的返回值可能为空的情况,对于这种情况程序员通常会采用如下方法:

public static String getName(User user) {
    if (user != null) {
        return user.getName();
    }
    return null;
}

这样做看似没有问题,但它有一个极大的缺点,那就是可能出现空指针错误。如果调用此方法时,传入的user参数是null,那么程序将会抛出NullPointerException异常。

为了避免这种情况的发生,我们通常会在方法的注释中明确说明返回值可能为空,例如:

/**
* 获取用户姓名,可能为空
* @param user 用户对象
* @return String
*/
public static String getName(User user)

但这样的做法还是存在问题,因为它只是告诉调用者可能会出现null值,并没有任何实际防止null的措施。

于是,Java 8中引入了Optional类解决这个问题。

二、Optional类的详解

1、Optional类的定义

Optional类是一个可以为null值提供可选选择的容器类,它最多只包含一个非null的值。Optional类的定义如下:

public final class Optional
    extends Object

  

Optional类是一个泛型类,其类型参数T表示optional对象可能包含的类型(例如:Optional<String>)。注意到,Optional是一个final类,因此无法被继承。

2、Optional类的创建

创建Optional实例的方法有两个:

  • Optional.of(T value):创建一个包含非空值的Optional。如果传入的是null,将会抛出NullPointerException。
  • Optional.empty():创建一个空的Optional。

示例代码:

Optional<String> optional1 = Optional.of("Hello");
Optional<String> optional2 = Optional.empty();

3、Optional类的判断

Optional类提供了以下几个判断方法:

  • isPresent():如果Optional中包含非空值,返回true;否则返回false。
  • ifPresent(Consumer<? super T> consumer):如果Optional中包含非空值,执行给定的操作;否则什么也不做。
  • orElse(T other):如果Optional中包含非空值,返回该值;否则返回传入的默认值。
  • orElseGet(Supplier<? extends T> supplier):如果Optional中包含非空值,返回该值;否则返回由Supplier提供的默认值。
  • orElseThrow(Supplier<? extends X> exceptionSupplier):如果Optional中包含非空值,返回该值;否则使用由Supplier提供的异常工厂方法抛出异常。

示例代码:

Optional<String> optional = Optional.of("Hello");

// 判断是否包含值
if (optional.isPresent()) {
    System.out.println(optional.get());
}

// 执行操作
optional.ifPresent(System.out::println);

// 获取值或默认值
String str1 = optional.orElse("World");
String str2 = optional.orElseGet(() -> "World");

// 抛出异常
String str3 = optional.orElseThrow(() -> new IllegalArgumentException("no value exists"));

4、Optional类的转换

Optional类提供了以下两个转换方法:

  • map(Function<? super T, ? extends U> mapper):如果Optional中包含非空值,对该值进行转换并返回一个Optional包含转换后的结果。否则返回空Optional。
  • flatMap(Function<? super T, ? extends Optional<? extends U>> mapper):如果Optional中包含非空值,对该值进行转换并返回一个Optional包含转换后的结果。否则返回空Optional。

示例代码:

Optional<String> optional = Optional.of("Hello");

// 转换
Optional<Integer> length = optional.map(String::length);

// 打印
length.ifPresent(System.out::println);

三、Java Optional的优缺点

1、Java Optional的优点

使用Java Optional类的好处有:

  • 强制程序员进行null检查,避免空指针异常。
  • 代码更容易阅读,代码的意义更清晰。
  • 减少了条件语句的使用,提高代码简洁度。

2、Java Optional的缺点

Java Optional类的缺点有:

  • 可能会导致性能下降。
  • 需要更多的方法调用,可能增加代码的复杂性。
  • Java Optional类并不是万能的,有些场景并不适合使用。

四、Java Optional的应用场景

Java Optional类的应用场景有:

  • 方法返回值可能为空的情况,比如:Optional<User> getUser(String name)
  • 给对象成员变量赋值时,比如:this.name = Optional.ofNullable(name).orElse("defaultName");
  • 多个Optional对象的组合,比如:Optional<String> name = Optional.ofNullable(user).flatMap(User::getName);

五、总结

Java Optional类是Java 8中引入的一个新特性,它可以帮助程序员有效地避免空指针异常,并且提高代码的简洁度。在实际开发中,我们应该充分利用Java Optional类来写出更加健壮、清晰的代码。