Optional
Optional 主要解决的问题: NullPointerException
文档说明
- Option 是一个容器对象,可能包含,也可能不包含一个非null的值
- 它是一个基于值的对象
- 被 final 修饰,不可变(允许包含指向可变对象的引用);
- 有 equals、hashCode、toString 方法的实现,但只仅仅是通过实例本身的状态来得出的;
- 不会使用敏感的操作,如实例之间的相等(==)、实例之间的 hashCode 比较、对象内置的锁的操作
- 被认为是 equal 的情况,仅仅基于 equals 方法,而不会基于引用相等性(==);
- 无可访问的构造方法(构造方法私有),实例通过工厂方法创建,工厂不保证返回实例的一致性;
- 当相等时,它们可以自由替换,当 equals 方法返回 true 时,x 与 y 可以任意交换
方法
工厂方法
- empty:构造一个容器里为 null 的对象(值为 null 的 Optional)
- of(T t):构造一个非空 Optional,若 T 为 null,则报空指针异常
- ofNullable(T t):构造一个里面值可能为 null,也可能不为 null 的 Optional 对象
常用操作方法
- get:将 value 取出
- ifPresent:判断容器中是否有对象存在
一般会在有可能出现 NullPointerException 的地方,通过 ofNullable 构造一个 Optional 并返回;然后获取对象时,通过 ifPresent 判断对象是否为 null
例子
有一个 Student 类
public class Student { private String name; private Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{name=" + name + ", age=" + age + '}'; } }
分别通过不同方式构造 Optional 并打印的结果如下
import java.util.Optional; public class OptionTest { public static void main(String[] args) { Optional<Object> empty = Optional.empty(); Optional<Student> of1 = Optional.of(new Student("Tom", 18)); Student s = null; // Optional<Student> of2 = Optional.of(s); // NullPointerException Optional<Student> ofNullable = Optional.ofNullable(s); // System.out.println(empty.get()); // NoSuchElementException System.out.println(of1.get()); // Student{name=Tom, age=18} // System.out.println(of2.get()); // 不会执行 // System.out.println(ofNullable.get()); // NoSuchElementException System.out.println(empty.isPresent()); // false System.out.println(of1.isPresent()); // true System.out.println(ofNullable.isPresent()); // false } }
最后,关于使用 Optional 的注意点
- 不要将 Optional 作为方法参数或者在类中声明为成员变量
- Optional 没有实现 Serializable 接口
- Optional 通常只作为方法的返回值,用于规避空指针异常