使用Optional.ofNullable来替换三元运算符是一种很好的做法



考虑以下表达式的用法:

String hi = Optional.ofNullable(sayHi()).orElse("-");

它有效地对应于这个三元表达式:

String hi = sayHi() != null ? sayHi() : "-";

Optional.ofNullable与方法调用一起使用是一种好的做法吗?或者只是额外的冗长编码?


我认识到Optional.ofNullable实际上创建了一个变量,并避免了两次调用sayHi()方法。为了避免这个问题,您实际上可以创建一个额外的变量,但这增加了三元选项的冗长性:

String hi = sayHi();
hi = hi != null ? hi : "-";

另一方面,Optional.ofNullablehi不是null的情况下创建额外的Optional对象。所以肯定会有更多的开销

因此,使用这种类型的构造来代替三元构造似乎有一些优点和缺点。


顺便说一句:这是Optional.ofNullable:的Java 8实现

public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}

在JDK 9或更高版本中,使用以下命令:

String hi = Objects.requireNonNullElse(sayHi(), "-");

这避免了在使用三元运算符时必须重复sayHi(),或者将其值分配给在三元运算符中重用的局部变量。这可能是一个小小的改进。它还回避了是否使用Optional的问题。:-)

每当我想到将可选API用于特定目的时,我总是提醒自己它的用途以及为什么将其引入JDK,即

中的可选,旨在为库方法提供有限的机制明确需要表示"无结果"的返回类型,以及其中使用null进行此操作极有可能导致错误-Stuart Marks

Optional主要关注可能有或没有返回值的返回类型。

像您的这个特定示例中那样过度使用这个构造只会导致额外的内存分配和GC开销。

我会保持简单的做法:

String hi = sayHi();
if(hi == null) hi = “-“;
...

Optional.ofNullable与方法调用一起使用是一种好的做法吗?

从概念上讲,这是一种糟糕的做法。基本思想是表示没有返回值,而不是包装可能是null的所有内容。我强烈反对这种用法。

或者只是额外的冗长编码?

在我看来,让您的代码更时尚的尝试失败了。("看,我们使用的是Java 8中全新的Optional!")

比起简洁,我更喜欢可读性和清晰度。

这种Optinal的使用并不能提供清晰的信息,但会引发问题:

为什么要包装变量
你打算用这个Optional做什么
会在下面使用/返回吗

它也不简洁:你的第二行甚至更短。

为了避免这个问题,您实际上可以创建一个额外的变量,但这增加了三元选项的复杂性。

您没有创建额外的变量。单行版本可以是:

String hi = (hi = sayHi()) != null ? hi : "-";

不过,你的两条线建议是绝对好的:

String messageContent = sayHi();
String hi = messageContent != null ? messageContent : "-";

如果您要允许Optional进入您的工作流程,那么您应该考虑修改sayHi()方法,使其返回Optional<String>,这将使结果更加优雅:

hi = sayHi().orElse("-");

如果您不想在工作流中引入Optional(因为它确实创建了一个包含可选值的附加对象),那么您最好坚持使用简单的null检查和三元运算符。

关于Optional的性能成本(例如增加的垃圾收集),您需要对应用程序进行概要分析,并决定这是否是一个真正的问题。

此外,如果您对String最感兴趣,那么请注意Objects.toString(Object, String)方法,如果对象为null,它将返回默认值:

hi = Objects.toString(hi, "-");

这比手动编写代码更整洁、更优雅。

简而言之:避免使用Optional类型。Optional关于返回类型的主要论点是,"客户端很容易忘记处理null返回值的可能性。Optional很难看,而且在你面前,所以客户端不太可能忘记处理空返回值的可能。在其他地方,程序员应该继续使用可能为null的正常引用。">

我写了一篇关于使用Java的Optional类型的利弊的讨论:没有什么比Optional类型更好的了。

我认为这主要是个人品味的问题。

从我的角度来看,只返回一个Optional<String>并让调用者处理缺失的值会更有意义。

可选,作为一个monadic类型,可以利用它获得更多的值,而不仅仅是一个alt值。

在另一端,您的运算符似乎足够简洁,如果使用一致,它可能是实用的。

我认为性能在这里不是什么大问题。

相关内容

最新更新