【发布时间】:2019-06-05 08:56:02
【问题描述】:
我已经阅读了很多关于应该使用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 方面存在差异?
【问题讨论】:
-
虽然我不了解 Scala 实践,但我还没有真正看到过使用
Optional作为实例变量的 Java 示例最终可以为您带来任何好处。根据我的经验,某些方法读取可空变量的值可能很方便,但只是将负担转移到设置它的方法上。也就是说,我已经看到带有Optional实例变量的代码可以毫无问题地工作(我一开始就不会编写它)。 -
我从使用它中看到的主要优点是,对于刚接触代码的人来说,很清楚某些内容可能为空/null。它还使您更多地考虑如果变量为空会发生什么,因为有时人们会忘记变量可以为空。无论如何,这是 Scala 中采用的方法。在示例代码中,除非您检查 getter 返回的内容,否则您不会知道变量可能为 null。
-
非常重要的区别是,
Optional是不可序列化的,所以如果你创建了任何带有Optional字段的类,你将无法序列化它。来自 Scala 的Option是可序列化的,正如您所注意到的,创建Option字段是常见的做法。正如我需要提到的,来自 Vavr 的Option是可序列化的,所以如果你想用Optionscala-style 创建字段,只需使用 Vavr. -
IMO 主要是封装问题。当您将方法声明为返回
Optional时,很明显可能会出现空结果,而无需查看代码甚至文档。如果您正在查看成员变量,那么您已经在查看代码。 -
Java
Optional并非设计用于成员变量。有许多问题 - 例如,如果它打算用于成员变量,它应该实现Serializable。请参阅:dzone.com/articles/optional-anti-patterns 和:dolszewski.com/java/java-8-optional-use-cases 这是经过深思熟虑的设计选择。