当前位置: 首页 > 知识库问答 >
问题:

为什么不对实例变量使用可选的?

通骁
2023-03-14

我读了很多关于应该使用可选的案例。

我读过的许多页面都说可选不应该用于私有实例变量,而应该由getters返回。

我认为将私有实例变量作为可选变量仍然是有用的。如果有人查看我的代码,他们可以看到一个值可以是空的,而不必检查留档是否可以返回空。

在Scala中,null从未使用过,它只是用于与Java的互操作性。如果值可以为null,建议始终使用可选值。这种方法对我来说更有意义。

这里有一页提到了它:

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的返回类型之前,您不知道邮政编码可能为空。如果您是新代码,您可能会错过这个添加扩展类,导致空指针异常

这里有一个关于Scala的选项的问题。

何时使用选项

为什么Java和Scala在如何使用可选性方面存在差异?

共有3个答案

潘驰
2023-03-14

有一个位置,可选的,像流一样,是一个迭代的“事件”类,不值得在“真实”对象中用作字段。

然后是不可序列化的缺点(这一点可以绕过)。

然而,我的观点是,有些变量可能是可选的,基数0和1。就像列表也是有效的一样。对于List字段,趋势是(恕我直言)最初不要让它为空,而是总是有一个(空)列表。

在相同的编码样式中,可选确保只使用安全访问,尤其是可以以链接样式映射:

Optional<TextField> t = ...

String s = t.map(t::getText).orElse("N/A");
Optional<String> u = t.map(t::getText);
t.ifPresent(s -> { ... });

尤其是ifPresent确保了不间断地使用null。

可选是一个有价值的规范。

茹康裕
2023-03-14

在Scala中,Option紧密集成到语言的API中。

表示可选值。Option的实例可以是scala的实例。有些人或物体没有。使用scala最惯用的方法。选项实例是将其视为一个集合或monad,并使用map、flatMap、filter或foreach。

从上面的引文中可以看出,这里没有null解释,因为它应该用作单子或集合。

在Java,可选用于将我们从NullPointerExcture案例中拯救出来,方法是将其用作:

一个容器对象,可能包含也可能不包含非空值。如果存在值,isPresent()将返回true,get()将返回该值。

一种非常清楚地向用户显示变量是否可以为null的编程语言是Kotlin,通过使用?安全调用,并显示编译错误:

var a: String = "abc"
a = null // compilation error

var b: String? = "abc"
b = null // ok
print(b)
范承教
2023-03-14

并非所有Java开发人员都同意您描述的方法。请查看Lombok创作者的帖子。

我想在Java中使用可选的不同方法的原因是Java社区直到Java8都没有它,所以大多数人习惯了null。一方面,许多新的API(如findanyfromStream)返回可选的,但仍有许多标准库方法只是返回null,因此您必须始终记住要么将函数调用包装为Optional.ofNullable或检查值是否为null。

可选的被添加到Java8中,但是不鼓励将其用作类字段,因为可选的没有实现Serializable(并且Java的序列化被许多框架或html" target="_blank">系统(如Akka、Spark、Kafka等)用作默认的序列化引擎。)。

另一方面,选项与Scala标准库紧密相连。据我所知,没有Scala的标准库API返回null,但是选项,不建议在Scala代码中使用null。您甚至可以配置项目,使其在使用null时无法编译。

选项也是可序列化的,它的通常做法是作为可以为空的值的类字段使用。

如果您想在Java代码中使用类似的方法,请选中Vavr中的选项。它是可序列化的,因此可以安全地用作字段,它还有两个子类NoneSome(类似于Scala的选项),因此可以用于Vavr的模式匹配:

Match(option).of(
    Case($Some($()), "defined"),
    Case($None(), "empty")
);
 类似资料:
  • 问题内容: 我读了这个问题不可变对象,并留下了关于不可变对象,并最终场一个问题: 为什么我们需要不可变类中的实例变量为最终变量? 例如,考虑以下不可变的类: 如果在上面的代码中没有set方法,而实例变量仅在构造函数中设置,为什么要求将实例变量声明为final? 问题答案: 有没有 要求 这样做的变量。但是,当您确实明确打算永远不更改变量时,通常这样做是一种好习惯,因为这不仅可以使变量避免错别字或其

  • 在《生锈的一生》一章中,有一个例子: 为什么他们使用

  • 我读到了这个关于不可变对象的问题,留下了一个关于不可变对象和final字段的问题: 为什么我们需要不可变类中的实例变量成为最终变量? 例如,考虑这个不可变类: 如果在上面的代码中没有设置方法,并且实例变量只在构造函数中设置,那么为什么需要将实例变量声明为final?

  • 问题内容: 我有一类具有各种成员变量的类。有一个构造函数,有getter方法,但没有setter方法。实际上,该对象应该是不变的。 现在我注意到了以下几点:当我使用getter方法获得变量列表时,可以添加新值,依此类推- 可以更改。下次调用此变量时,将返回更改的内容。怎么会这样?我没有再设置它,我只是在做它!使用这种行为是不可能的。那么这里有什么区别? 问题答案: 仅仅因为 对 列表 的引用 是不

  • 当使用Java8类时,有两种方法可以将值包装到Optional中。 我理解是使用的唯一安全方法,但为什么?为什么不直接使用