Optional是Java8提供的为了办理null安详问题的一个API。善用Optional可以使我们代码中许多繁琐、丑恶的设计变得十分优雅。这篇文章是成立在你对Optional的用法有必然相识的基本上的,假如你还不太相识Optional,可以先去看看相关教程,可能查阅Java文档。
利用Optional,我们就可以把下面这样的代码举办改写。
public static String getName(User u) {
if (u == null)
return "Unknown";
return u.name;
}
public static String getName(User u) {
Optional<User> user = Optional.ofNullable(u);
if (!user.isPresent())
return "Unknown";
return user.get().name;
}
这样改写非但不简捷,并且其操纵照旧和第一段代码一样。无非就是用isPresent要领来替代u==null。这样的改写并不是Optional正确的用法,我们再来改写一次。
public static String getName(User u) {
return Optional.ofNullable(u)
.map(user->user.name)
.orElse("Unknown");
}
这样才是正确利用Optional的姿势。那么凭据这种思路,软件开发,我们可以定心的举办链式挪用,而不是一层层判定了。看一段代码:
public static String getChampionName(Competition comp) throws IllegalArgumentException {
if (comp != null) {
CompResult result = comp.getResult();
if (result != null) {
User champion = result.getChampion();
if (champion != null) {
return champion.getName();
}
}
}
throw new IllegalArgumentException("The value of param comp isn't available.");
}
由于各种原因(好比:角逐还没有发生冠军、要领的非正常挪用、某个要领的实现里埋藏的大礼包等等),我们并不能开心的一路comp.getResult().getChampion().getName()到底。而其他语言好比kotlin,就提供了在语法层面的操纵符加持:comp?.getResult()?.getChampion()?.getName()。所以讲原理在Java里我们怎么办!
让我们看看颠末Optional加持事后,这些代码会酿成什么样子。
public static String getChampionName(Competition comp) throws IllegalArgumentException {
return Optional.ofNullable(comp)
.map(c->c.getResult())
.map(r->r.getChampion())
.map(u->u.getName())
.orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}
这就很舒服了。Optional给了我们一个真正优雅的Java气势气魄的要领来办理null安详问题。固然没有直接提供一个操纵符写起来短,可是代码看起来依然很爽很舒服。更况且?.这样的语法好欠悦目还见仁见智呢。
尚有许多不错的利用姿势,好比为空则不打印可以这么写:
string.ifPresent(System.out::println);
Optional的魅力还不止于此,Optional尚有一些神奇的用法,好比Optional可以用来检讨参数的正当性。
public void setName(String name) throws IllegalArgumentException {
this.name = Optional.ofNullable(name).filter(User::isNameValid)
.orElseThrow(()->new IllegalArgumentException("Invalid username."));
}
这样写参数正当性检测,应该足够优雅了吧。
参考资料