现在已经使用 Java 8 6 个多月了,我对新的 API 更改非常满意。我仍然不确定的一个领域是何时使用 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
:
一般来说,我不认为:
List<Optional<Foo>>
添加任何东西 - 特别是因为可以使用 filter()
删除 null
值等,但是 Optional
在集合中有什么好的用途吗?
有什么我错过的案例吗?
原文由 Will 发布,翻译遵循 CC BY-SA 4.0 许可协议
Optional
的主要设计目标是为函数返回值提供一种方法,以指示没有返回值。请参阅 此讨论。 这允许调用者继续一系列流畅的方法调用。这与 OP 问题中的用例 #1 最接近。虽然, 没有值 是比 null 更精确的公式,因为像
IntStream.findFirst
这样的东西永远不会返回 null。对于用例 #2 ,将可选参数传递给方法,这可以使其工作,但它相当笨拙。假设您有一个方法,该方法接受一个字符串,后跟一个可选的第二个字符串。接受
Optional
作为第二个参数将产生如下代码:即使接受 null 也更好:
可能最好的方法是拥有一个接受单个字符串参数并为第二个提供默认值的重载方法:
这确实有局限性,但它比上述任何一个都好得多。
用例 #3 和 #4 在类字段或数据结构中具有
Optional
被视为对 API 的滥用。首先,它违背了Optional
的主要设计目标,如顶部所述。其次,它没有增加任何价值。处理
Optional
中缺少值的三种方法:提供替代值、调用函数以提供替代值或抛出异常。如果要存储到字段中,则应在初始化或分配时执行此操作。如果您将值添加到列表中,正如 OP 所提到的,您可以选择简单地不添加值,从而“拉平”不存在的值。我敢肯定,有人可能会想出一些人为的案例,他们真的想在字段或集合中存储
Optional
,但总的来说,最好避免这样做。