为什么可选的不用于实例变量?
Why isn't optional used for instance variables?
我已经阅读了很多关于应该使用 Optional
的案例。
我读过的很多页面都说 Optional
不应该用于私有实例变量,而应该由 getter 编辑 return。
我原以为将私有实例变量作为可选变量仍然有用。如果有人查看我的代码,他们可以看到值可以为空,而不必检查文档以查看 null 是否可以 returned。
在 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 的 return 类型之前,您不知道邮政编码可能为空。如果您是代码的新手,您可能会错过此添加扩展 class,从而导致空指针异常。
这里有一个关于 Scala Option
的问题。
When to use Option
为什么 Java 和 Scala 的可选用法不同?
在 Scala 中,Option 与语言的 API 紧密集成。
Represents optional values. Instances of Option are either an instance of scala.Some or the object None.
The most idiomatic way to use an scala.Option instance is to treat it as a collection or monad and use map,flatMap, filter, or foreach.
从上面的引用可以看出,那里没有null
解释,因为它应该用作monad或集合。
在 Java 中,Optional 用于将我们从 NullPointerException 情况中拯救出来,将其用作:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
一种可以非常清楚地向用户显示变量是否可以为 null 的编程语言是 Kotlin, by using ? safe call,并向您显示编译错误:
var a: String = "abc"
a = null // compilation error
var b: String? = "abc"
b = null // ok
print(b)
并非所有 Java 开发人员都同意您描述的方法。请查看 Lombok 的创建者的 。
我想在 Java 中使用 Optional
的不同方法的原因是 Java 的社区在 Java 8 之前没有它,所以大多数人习惯于 null。一方面有很多新的 API(比如 Stream
中的 findAny
)return Optional
,但仍然有很多标准库方法只是 return null,因此您始终必须记住用 Optional.ofNullable
包装函数调用或检查值是否不为空。
Optional
已添加到 Java 8,但不鼓励将其用作 class 字段,因为 Optional
未实现 Serializable
(并且 Java的序列化被许多框架或系统(如 Akka、Spark、Kafka 等)用作默认序列化引擎。
另一方面,Option
与 Scala 标准库紧密结合。
据我所知,没有 Scala 的标准库 APIs return null,但是 Option
,不鼓励使用 null 在你的 Scala 代码中。如果 null 为 used.
,您甚至可以将项目配置为编译失败
Option
也是 Serializable
,它的正常使用方式是 class 值字段可以为空。
如果您想在 Java 代码中使用类似的方法,请检查 Vavr 中的 Option。它是可序列化的,所以它可以安全地用作字段而且它还有两个子classes None
和Some
(类似于Scala的Option
),所以它可以被使用在 Vavr 的模式匹配中:
Match(option).of(
Case($Some($()), "defined"),
Case($None(), "empty")
);
有一种观点认为,Optional 与 Stream 一样,是一个迭代的“事件”class,不适合用作 "real" 对象中的字段。
然后是不可序列化的 short-coming(这可能会解决)。
但是我认为某些变量可能是可选的,基数为 0 和 1。
正如 list 也是有效的。对于 List
字段,趋势是(恕我直言)最初不允许它为空,但总是有一个(空)列表。
在相同的编码风格中,Optional
确保只使用安全访问,尤其是可以映射为链接风格:
Optional<TextField> t = ...
String s = t.map(t::getText).orElse("N/A");
Optional<String> u = t.map(t::getText);
t.ifPresent(s -> { ... });
特别是 ifPresent
确保不会无意中使用 null。
可选的是一个有价值的规范。
不对实例变量使用 Optional
的一个原因是 Optional
引用本身很容易成为 null
。这违反了围绕 Optional
的隐含契约,即您永远不应创建或遇到对 Optional
.
的 null
引用
class Foo {
Optional<Bar> bar;
}
Foo f = new Foo();
if (f.bar.isPresent()) { // NullPointerException
...
}
这是在 Java 中使用 Optional
字段创建 class 的最简单方法。从某种意义上说,该语言鼓励您编写这样的代码。
另一方面,在 Scala 中,定义 Foo
的最简单方法是
case class Foo(bar: Option[Bar])
而且很容易做到
case class Foo(bar: Option[Bar] = None)
两者都避免了NPE
我已经阅读了很多关于应该使用 Optional
的案例。
我读过的很多页面都说 Optional
不应该用于私有实例变量,而应该由 getter 编辑 return。
我原以为将私有实例变量作为可选变量仍然有用。如果有人查看我的代码,他们可以看到值可以为空,而不必检查文档以查看 null 是否可以 returned。
在 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 的 return 类型之前,您不知道邮政编码可能为空。如果您是代码的新手,您可能会错过此添加扩展 class,从而导致空指针异常。
这里有一个关于 Scala Option
的问题。
When to use Option
为什么 Java 和 Scala 的可选用法不同?
在 Scala 中,Option 与语言的 API 紧密集成。
Represents optional values. Instances of Option are either an instance of scala.Some or the object None. The most idiomatic way to use an scala.Option instance is to treat it as a collection or monad and use map,flatMap, filter, or foreach.
从上面的引用可以看出,那里没有null
解释,因为它应该用作monad或集合。
在 Java 中,Optional 用于将我们从 NullPointerException 情况中拯救出来,将其用作:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
一种可以非常清楚地向用户显示变量是否可以为 null 的编程语言是 Kotlin, by using ? safe call,并向您显示编译错误:
var a: String = "abc"
a = null // compilation error
var b: String? = "abc"
b = null // ok
print(b)
并非所有 Java 开发人员都同意您描述的方法。请查看 Lombok 的创建者的
我想在 Java 中使用 Optional
的不同方法的原因是 Java 的社区在 Java 8 之前没有它,所以大多数人习惯于 null。一方面有很多新的 API(比如 Stream
中的 findAny
)return Optional
,但仍然有很多标准库方法只是 return null,因此您始终必须记住用 Optional.ofNullable
包装函数调用或检查值是否不为空。
Optional
已添加到 Java 8,但不鼓励将其用作 class 字段,因为 Optional
未实现 Serializable
(并且 Java的序列化被许多框架或系统(如 Akka、Spark、Kafka 等)用作默认序列化引擎。
另一方面,Option
与 Scala 标准库紧密结合。
据我所知,没有 Scala 的标准库 APIs return null,但是 Option
,不鼓励使用 null 在你的 Scala 代码中。如果 null 为 used.
Option
也是 Serializable
,它的正常使用方式是 class 值字段可以为空。
如果您想在 Java 代码中使用类似的方法,请检查 Vavr 中的 Option。它是可序列化的,所以它可以安全地用作字段而且它还有两个子classes None
和Some
(类似于Scala的Option
),所以它可以被使用在 Vavr 的模式匹配中:
Match(option).of(
Case($Some($()), "defined"),
Case($None(), "empty")
);
有一种观点认为,Optional 与 Stream 一样,是一个迭代的“事件”class,不适合用作 "real" 对象中的字段。
然后是不可序列化的 short-coming(这可能会解决)。
但是我认为某些变量可能是可选的,基数为 0 和 1。
正如 list 也是有效的。对于 List
字段,趋势是(恕我直言)最初不允许它为空,但总是有一个(空)列表。
在相同的编码风格中,Optional
确保只使用安全访问,尤其是可以映射为链接风格:
Optional<TextField> t = ...
String s = t.map(t::getText).orElse("N/A");
Optional<String> u = t.map(t::getText);
t.ifPresent(s -> { ... });
特别是 ifPresent
确保不会无意中使用 null。
可选的是一个有价值的规范。
不对实例变量使用 Optional
的一个原因是 Optional
引用本身很容易成为 null
。这违反了围绕 Optional
的隐含契约,即您永远不应创建或遇到对 Optional
.
null
引用
class Foo {
Optional<Bar> bar;
}
Foo f = new Foo();
if (f.bar.isPresent()) { // NullPointerException
...
}
这是在 Java 中使用 Optional
字段创建 class 的最简单方法。从某种意义上说,该语言鼓励您编写这样的代码。
另一方面,在 Scala 中,定义 Foo
的最简单方法是
case class Foo(bar: Option[Bar])
而且很容易做到
case class Foo(bar: Option[Bar] = None)
两者都避免了NPE