java - 为什么不可选用于实例变量?
问题描述
我一直在阅读很多关于Optional
应该使用的案例。
我读过的很多页面都说Optional
不应该用于私有实例变量,而应该由 getter 返回。
我原以为将私有实例变量作为可选变量仍然很有用。如果有人查看我的代码,他们可以看到一个值可以为空,而不必检查文档以查看是否可以返回 null。
在 Scala 中,null 从不使用,只是为了与 Java 进行互操作。如果值可以为空,建议始终使用可选项。这种方法对我来说更有意义。
这是一个提到它的页面:
https://blog.joda.org/2015/08/java-se-8-optional-pragmatic-approach.html
这是示例代码。
private final String addressLine; // never null
private final String city; // never null
private final String postcode; // optional, thus may be null
// normal getters
public String getAddressLine() { return addressLine; }
public String getCity() { return city; }
// special getter for optional field
public Optional<String> getPostcode() {
return Optional.ofNullable(postcode);
}
我能看到的唯一优点是,如果你想序列化对象,现在可以,因为它没有将可选存储在变量中。
缺点是在检查 getter 的返回类型之前,您不知道 postcode 可能为 null。如果您不熟悉代码,您可能会错过这个添加扩展类,从而导致空指针异常。
这是一个关于 Scala 的问题Option
。
为什么 Java 和 Scala 在应该如何使用 optional 方面存在差异?
解决方案
并非所有 Java 开发人员都同意您描述的方法。请查看 Lombok 的创建者的这篇文章。
我猜想在 Java 中使用不同方法的原因Optional
是 Java 社区在 Java 8 之前一直没有它,所以大多数人习惯于null。一方面,很多新的 API(比如findAny
from Stream
)返回Optional
,但仍然有很多标准库方法只返回null,所以你总是必须记住要么包装你的函数调用,Optional.ofNullable
要么检查值是否不为 null。
Optional
已添加到 Java 8,但不鼓励将其用作类字段,因为Optional
它没有实现Serializable
(并且 Java 的序列化被许多框架或系统(如 Akka、Spark、Kafka 等)用作默认序列化引擎)。
另一方面Option
,它与 Scala 标准库的绑定非常紧密。据我所知,没有 Scala 的标准库 API 返回null , 但是Option
,并且不鼓励在 Scala 代码中使用null 。您甚至可以配置您的项目,如果使用null,它将无法编译。
Option
也是Serializable
,其通常使用的做法是作为可以为空的值的类字段。
如果您想在 Java 代码中使用类似的方法,请检查Vavr中的选项。它是可序列化的,因此可以安全地用作字段,并且它还有两个子类和(类似于 Scala 的),因此可以在 Vavr 的模式匹配中使用:None
Some
Option
Match(option).of(
Case($Some($()), "defined"),
Case($None(), "empty")
);
推荐阅读
- c++ - 如何从用户控制台输入中读取多个字符串行?
- react-native - React Native:如何将导航作为道具从功能组件传递到类组件
- amazon-web-services - Rasa 服务器的 ALB 配置获得不健康检查
- javascript - 为什么回调后组件不重新渲染?
- scalardb - 如何使用 ScalarDB 在 Cassandra 中查找分区的大小
- php - 无法在php中读取配置文件
- sql - SSRS/SQL 如何在图表上绘制 HH:mm:ss?
- javascript - 获取字段的JS名称
- android - Activity 中未显示回收站视图
- javascript - 站点如何检测 --remote-debugging-port chrome 开关