在Java 8之前,要编写一个在特定环境下无法返回任何值的方法时,有两种方法:要么抛出异常,要么返回null(假设这里返回类型是一个对象引用类型)。但这两种方法都不够完美。通常情况下异常应该根据异常条件保留下来,java培训因为创建异常时会捕捉整个堆栈轨迹,抛出异常的成本很高;返回null则要求客户端必须包含特殊的代码来处理null值。
而在Java 8中,还有第三种方法可以编写不能返回值的方法。Optional<T>类代表的是一个不可变的容器,它可以存放单个非null的T引用,或者什么内容都没有。通常不包含任何内容的Optional称为空,非空的Optional中的值称作存在。Optional本质上是一个不可变的集合,最多只能存放一个元素。Optional<T>没有实现Collection<T>接口,但原则上是可以的。
public T get(String id) { if (StringUtils.isNullOrBlank(id)) { return null; } return testService.get(id); }
上述代码,当id传入空时,返回null。理论上所有能返回T的方法,都可以改成返回Optional<T>,比如:
public Optional<T> get(String id) { if (StringUtils.isNullOrBlank(id)) { return Optional.empty(); } return Optional.ofNullable(testService.get(id)); }
如上所示,返回Optional是很简单的事,只要用适当的静态工厂创建Optional即可。在这里Optional.empty()返回一个空的Optional,Optional.ofNullable接受可能为null的值,当传入null值就返回一个空的Optional。但我们需要记住的一点是:「永远不要通过返回Optional的方法返回null」,因为它彻底违背了Optional的本意。
如果方法返回Optional,客户端必须要做出选择:如果该方法不能返回值时应该采取什么样的措施。抛出异常?提供默认值?
Optional提供isPresent()方法,它可以被当做是一个安全阈。当Optional中包含一个值时,它返回true;当Optional为空时,返回false。通常我们可以这么使用:
Optional<Test> optional = testService.get(id); if (optional.isPresent() == false) { return; } Test test = optional.get(); // do something
当然Optional也提供orElse(T other)当值为空时,使用某个默认值的方法。
关于更多Optional的用法还请大家自行学习使用。
总而言之,如果发现自己在编写的方法始终无法返回值,并且使用该方法的客户端每次在调用它时都要考虑到这种可能性,那么或许就应该返回一个Optional
联系客服