让我们先来看看Optional(在Java8中引入)是做什么的?
Optional是对一个对象的封装,提供了安全处理底层对象的方法,同时避免了可怕的空指针异常。
这提供了与Kotlin的nullable数据类型基本相同的行为,并允许Java有办法模仿Kotlin的nullable数据类型。
而Java没有的是一个与Kotlin相匹配的非空类型:你不能阻止将null赋值给一个变量。
那么我们怎么做呢?
我们可以假设所有不是Optional的东西都是非空的。
最好是为IDE和编译器的警告做注解,以帮助我们(可能的话还可以使用Lombok在运行时尽可能地执行它):
@Nonnull |
注意:所有的Java返回类型和参数都被标记为@Nonnull - 意味着我们不希望在代码中看到任何null。
相反,可以使用Optional.empty();这是一个更明确的指示,即不打算存在任何值,而只是缺少。
Kotlin:
fun constructMyMessage(message: String, name: String?): String { |
对于Java来说,这将使Optional Everywhere。
当一个值可能为空时,用一个Optional来包装它,适用于返回类型、方法参数和成员变量。
通过这种方法,你可以避免大多数你可能需要写null的情况。相反,你可以使用Optional类所提供的方法来操作底层的值。一些有用的方法。
- ifPresent(Consumer<? super T> consumer)如果值是存在的并且不是空的,就执行consumer 。
- map(Function<? super T, ? extends U> mapper)使用mapper将底层值转换为一个新的类型。
- orElse(T other) 如果底层值为空,则返回底层值或其他。这允许你保证检索到一个非空值。
还有很多可以用Optionals做的事情,可以在Java 8、11和17文档中找到。
我曾经是只把Optional作为返回类型的阵营,但在与Kotlin和Swift一起工作后,我已经改用Optional了。
这如何适用于集合Collections?
在可能的情况下,如果不需要区分空的情况和空的情况,最好使用空的集合而不是空的集合。如果需要区分空集和空集(比如PATCH请求),可以使用一个Optional来区分集合的两种状态。
遵循这种方法,你的代码库将更接近于Kotlin,而且还有一个额外的好处,那就是消除了大部分(如果不是全部)你可能遇到的十亿美元的错误的情况。