Java 8带有新的Optional
类型,类似于其他语言中提供的类型。 这篇文章将介绍这种新类型的使用方式,即主要用途。
什么是可选类型?
可选的是新容器类型,如果有可用值,则该容器类型将包装单个值。 因此,其含义是传达可能不存在该值的含义。 以这种方法为例:
public Optional<Customer> findCustomerWithSSN(String ssn) {...
}
返回Optional
显式增加了该给定的社会保险号可能没有客户的可能性。
这意味着类型系统明确地迫使该方法的调用者考虑并处理可能没有使用该SSN的客户的可能性。
呼叫者将必须执行以下操作:
Optional<Customer> optional = findCustomerWithSSN(ssn);if (optional.isPresent()) {Customer customer = maybeCustomer.get();... use customer ...
}
else {... deal with absence case ...
}
否则,请提供默认值:
Long value = findOptionalLong(ssn).orElse(0L);
可选的用法有点类似于抛出检查异常的更熟悉的情况。 通过抛出一个已检查的异常,我们使用编译器来强制API的调用者以某种方式处理异常情况。
可选试图解决什么?
可选的方法是尝试通过增加构建更具表现力的API的可能性来减少Java系统中空指针异常的数量,这些API解释了有时缺少返回值的可能性。
如果从一开始就存在Optional,那么大多数库和应用程序可能会更好地处理缺少的返回值,从而减少了空指针异常的数量以及总体上的错误总数。
那么应该如何使用Optional?
可选应该用作可能不返回值的函数的返回类型 。
这是来自OpenJDK邮件列表的报价 :
“ JSR-335 EG相当强烈地认为,“可选”的使用不应超过仅支持“可选-返回”惯用语所需的内容。
有人建议甚至将其重命名为OptionalReturn”
在域驱动程序开发的上下文中,这意味着Optional应该用作某些服务,存储库或实用程序方法的返回类型,例如上面显示的方法。
什么是可选的,不尝试解决
可选并不意味着是一种避免所有类型的空指针的机制。 例如,仍然必须测试方法和构造函数的强制输入参数。
像使用null时一样,Optional不能帮助传达缺失值的含义 。 以类似的方式,null可能意味着许多不同的东西(找不到值等),因此缺少Optional值也可以。
该方法的调用者仍然必须检查该方法的javadoc以了解缺少Optional的含义,以便正确处理它。
同样,可以将被检查的异常捕获到一个空块中,这也没有阻止调用方调用get()
并继续前进的方式。
仅返回null有什么问题?
问题在于该函数的调用者可能没有阅读该方法的javadoc,而忘记了处理null的情况。
这经常发生,并且是空指针异常的主要原因之一,尽管不是唯一的原因。
如何不使用可选?
可选不打算在这些情况下使用,因为它不会给我们带来任何好处:
- 在域模型层中(不可序列化)
- 在DTO中(相同原因)
- 在方法的输入参数中
- 在构造函数参数中
Optional对函数式编程有何帮助?
在链接的函数调用中,Optional提供了ifPresent()
方法,该方法允许链接可能不返回值的函数:
findCustomerWithSSN(ssn).ifPresent(() -> System.out.println("customer exists!"));
有用的链接
Oracle的这篇博客文章进一步介绍了Optional
及其用法,并将其与其他语言的类似功能进行了比较– 厌倦了Null指针异常?
该备忘单提供了Optional – Java 8 Cheat Sheet中的Optional的全面概述。
翻译自: https://www.javacodegeeks.com/2014/06/java-8-optional-how-to-use-it.html