现在已经使用 Java 8 6 个多月了,我对新的 API 更改非常满意。我仍然不确定的一个领域是何时使用Optional. 我似乎在想在任何地方都可以使用它null和根本无处使用它之间摇摆不定。
Optional
null
似乎在很多情况下我都可以使用它,但我不确定它是否会增加好处(可读性/空安全性)或只会导致额外的开销。
所以,我有几个例子,我会对社区关于是否Optional有益的想法感兴趣。
1 - 当方法可以返回时作为公共方法返回类型null:
public Optional<Foo> findFoo(String id);
2 - 作为方法参数,当参数可能是null:
public Foo doSomething(String id, Optional<Bar> barOptional);
3 - 作为 bean 的可选成员:
public class Book { private List<Pages> pages; private Optional<Index> index; }
4 - 在Collections:
Collections
一般来说,我不认为:
List<Optional<Foo>>
添加任何东西 - 特别是因为可以filter()用来删除值等,但是在集合null中有什么好的用途吗?Optional
filter()
有什么我错过的案例吗?
的主要设计目标Optional是为函数返回值提供一种方法,以指示没有返回值。请参阅此讨论。 这允许调用者继续一系列流畅的方法调用。
这与OP 问题中的用例 #1最接近。 虽然, 没有值 是比 null 更精确的表述,因为类似的东西IntStream.findFirst永远不会返回 null。
IntStream.findFirst
对于用例 #2 ,将可选参数传递给方法,这可以使其工作,但它相当笨拙。假设您有一个方法,该方法接受一个字符串,后跟一个可选的第二个字符串。接受 anOptional作为第二个参数将导致如下代码:
foo("bar", Optional.of("baz")); foo("bar", Optional.empty());
即使接受 null 也更好:
foo("bar", "baz"); foo("bar", null);
可能最好的方法是拥有一个接受单个字符串参数并为第二个提供默认值的重载方法:
foo("bar", "baz"); foo("bar");
这确实有局限性,但它比上述任何一个都好得多。
用例 #3 和 #4Optional在类字段或数据结构中具有一个,被认为是对 API 的滥用。首先,它违背Optional了顶部所述的主要设计目标。其次,它没有增加任何价值。
有三种方法可以处理 中的值缺失Optional:提供替代值、调用函数以提供替代值或抛出异常。如果要存储到字段中,则应在初始化或分配时执行此操作。如果您将值添加到列表中,正如 OP 所提到的,您可以选择简单地不添加值,从而“拉平”不存在的值。
我敢肯定,有人可能会想出一些人为的情况,他们真的想将 an 存储Optional在字段或集合中,但总的来说,最好避免这样做。