现在已经使用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值等,但是Optionalin集合有什么好的用处吗?
我错过了任何情况吗?
主要目的Optional是为函数提供一种返回值的手段,以指示不存在返回值。看到这个讨论。这使调用者可以继续进行一系列流畅的方法调用。
这与OP问题中的用例#1最接近。虽然,缺少值比空值更为精确,因为类似这样的IntStream.findFirst值永远不会返回空值。
IntStream.findFirst
对于用例2,将可选参数传递给方法,可以使之起作用,但这相当笨拙。假设你有一个方法,该方法接受一个字符串,然后是一个可选的第二个字符串。接受Optionalas作为第二个arg将导致如下代码:
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所述),则可以选择不添加值,从而“拉平”缺少的值。
我确信有人会提出一些他们确实想Optional在字段或集合中存储的人为设计的案例,但是总的来说,最好避免这样做。