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.")); }
这样写参数正当性检测,应该足够优雅了吧。
参考资料