现在已经使用Java 8超过6个月左右,我对新的API更改感到非常满意.我仍然不自信的一个领域是什么时候使用Optional.我似乎想要在任何可能的null地方使用它,而且无处可去.
似乎有很多情况我可以使用它,我不知道它是否增加了好处(可读性/无效安全性)或只是导致额外的开销.
所以,我有一些例子,我对社区是否Optional有益的想法感兴趣.
1 - 当方法可以返回时作为公共方法返回类型null:
public Optional<Foo> findFoo(String id);
Run Code Online (Sandbox Code Playgroud)
2 - 当参数可能是null以下时作为方法参数:
public Foo doSomething(String id, Optional<Bar> barOptional);
Run Code Online (Sandbox Code Playgroud)
3 - 作为bean的可选成员:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
Run Code Online (Sandbox Code Playgroud)
4 - 在Collections:
一般来说,我不认为:
List<Optional<Foo>>
Run Code Online (Sandbox Code Playgroud)
添加任何东西 - 特别是因为可以使用filter()删除null值等,但是Optional在集合中是否有任何好的用途?
我错过了什么案例?
在Java 8中,您可以返回Optional而不是a null.Java 8文档说可选是"容器对象,可能包含也可能不包含非空值.如果存在值,isPresent()将返回true,get()将返回值."
在实践中,为什么这有用?此外,是否有任何null优先使用的情况?性能怎么样?
假设我想执行以下命令:
house.getFloor(0).getWall(WEST).getDoor().getDoorknob();
Run Code Online (Sandbox Code Playgroud)
为了避免NullPointerException,我必须在以下情况下执行以下操作:
if (house != null && house.getFloor(0) && house.getFloor(0).getWall(WEST) != null
&& house.getFloor(0).getWall(WEST).getDoor() != null) ...
Run Code Online (Sandbox Code Playgroud)
是否有一种方法或已经存在的Utils类更优雅地执行此操作,让我们说类似下面的内容?
checkForNull(house.getFloor(0).getWall(WEST).getDoor().getDoorknob());
Run Code Online (Sandbox Code Playgroud) 在函数式语言中,通常在可选类型上使用模式匹配:
let result = match myOptional with
| Some x -> x * 2
| None -> 0
Run Code Online (Sandbox Code Playgroud)
这对程序员非常有帮助,因为编译器检查模式匹配是否完整.
然而,在Java的例子Optional,我所看到的,isPresent并且get被用来代替:
Integer result;
if (myOptional.isPresent()) {
result = myOptional.get() * 2;
} else {
result = 0;
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这违背了目的Optional.编译器不进行检查以确保if正确实现了它们的两个分支,并且生成的代码没有比使用等效代码更多的保证null.
这种设计选择阻碍了安全性,那么为什么标准库提供的get功能不仅仅是match?