Java Optional的创建,用户希望从现有值返回 Optional,使用 Optional.of、Optional.ofNullable 或 Optional.empty 方法。与 Java 8 新增的众多类一样,Optional 实例也是不可变的(immutable)。
Java Optional的创建 问题描述
用户希望从现有值返回 Optional。
Java Optional的创建 解决方案
使用 Optional.of、Optional.ofNullable 或 Optional.empty 方法。
Java Optional的创建 具体实例
与 Java 8 新增的众多类一样,Optional 实例也是不可变的(immutable)。API 将 Optional 称为基于值的类(value-based class),即 Optional 实例:
- 被声明为
final且是不可变 2 的(但可能包含对可变对象的引用); -
不提供公共构造函数(public constructor),因此必须采用工厂方法加以实例化;
-
具有
equals、hashCode与toString的实现,这些实现是通过实例的状态计算出来的。
2有关不可变性的讨论请参见“Optional 与不可变性”注释。
Optional与不可变性
Optional实例是不可变的,但它包装的对象却不一定是不可变的。如果创建一个包含可变对象实例的Optional,则仍然可以对实例进行修改,如例 6-1 所示。例 6-1
Optional是不可变的吗?
AtomicInteger counter = new AtomicInteger();
Optional<AtomicInteger> opt = Optional.ofNullable(counter);
System.out.println(optional); // Optional[0]
counter.incrementAndGet(); ➊
System.out.println(optional); // Optional[1]
optional.get().incrementAndGet(); ➋
System.out.println(optional); // Optional[2]
optional = Optional.ofNullable(new AtomicInteger()); ➌
❶ 直接使用计数器自增
❷ 检索包含的值并自增
❸ 可以对 Optional 引用重新赋值
我们既可以通过原始引用修改包含的值,也可以在 Optional 上调用 get 以检索某个值进行修改。我们甚至可以对引用本身重新赋值,换言之,不能将不可变性与 final 混为一谈。但是,无法对 Optional 实例本身进行修改,因为不存在能执行这种操作的方法。
对“不可变”的定义略显模糊,这在 Java 中并不鲜见。Java 并未提供一种良好的内置方式来创建只能产生无法改变的对象的类。
我们可以通过静态工厂方法 empty、of 与 ofNullable 来创建 Optional,三者的签名如下:
static <T> Optional<T> empty()
static <T> Optional<T> of(T value)
static <T> Optional<T> ofNullable(T value)
显而易见,empty 方法将返回一个空 Optional。如果参数为 null,of 方法将返回一个包装指定值或抛出异常的 Optional,其应用如例 6-2 所示。
例 6-2 通过
of方法创建Optional
public static <T> Optional<T> createOptionalTheHardWay(T value) {
return value == null ? Optional.empty() : Optional.of(value);
}
在本例中,createOptionalTheHardWay 之所以被命名为“The Hard Way”,并非因为它难以实现,而是存在另一种更简单的方法,这就是例 6-3 所示的 ofNullable 方法。
例 6-3 通过
ofNullable方法创建Optional
public static <T> Optional<T> createOptionalTheEasyWay(T value) {
return Optional.ofNullable(value);
}
在 Java 8 的引用实现中,ofNullable 方法的实现其实就是 createOptionalTheHardWay 中的语句:检查包含的值是否为 null,若是,则返回一个空 Optional,否则使用 of 方法进行包装。
此外,包装基本数据类型的 OptionalInt、OptionalLong 与 OptionalDouble 类不能为 null,因此三者只有 of 方法,没有 ofNullable 方法。
static OptionalInt of(int value)
static OptionalLong of(long value)
static OptionalDouble of(double value)
请注意,三个类的 getter 方法分别为 getAsInt、getAsLong 与 getAsDouble,而不是 getInt、getLong 与 getDouble。
极客教程