Java 使用Optional.ofNullable替换三元运算符是否是一种良好的做法?

Java 使用Optional.ofNullable替换三元运算符是否是一种良好的做法?,java,java-8,optional,nullable,Java,Java 8,Optional,Nullable,考虑此表达式的用法: String hi = Optional.ofNullable(sayHi()).orElse("-"); String hi = sayHi() != null ? sayHi() : "-"; 有效地对应于这个三元表达式: String hi = Optional.ofNullable(sayHi()).orElse("-"); String hi = sayHi() != null ? sayHi() : "-"; 在方法调用中使用是可选的吗?或者只是额外的冗

考虑此表达式的用法:

String hi = Optional.ofNullable(sayHi()).orElse("-");
String hi = sayHi() != null ? sayHi() : "-";
有效地对应于这个三元表达式:

String hi = Optional.ofNullable(sayHi()).orElse("-");
String hi = sayHi() != null ? sayHi() : "-";
在方法调用中使用
是可选的吗?或者只是额外的冗长编码


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

String hi = sayHi();
hi = hi != null ? hi : "-";
另一方面,
可选。如果
hi
不是
null
的话,ofNullable会创建一个额外的
可选的
对象。因此,肯定会有更多的开销

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


顺便说一句:这是
可选的Java8实现

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}
public静态可选空值(T值){
返回值==null?空():of(值);
}

< /代码> 如果您允许将<>代码>可选/<代码>放入您的工作流程中,那么您应该考虑修改<代码> sayh()>代码>方法,使其返回<代码>可选< /代码>,这将使结果更加优雅:

hi = sayHi().orElse("-");
如果不想在工作流中引入
Optional
(因为它确实创建了一个包含可选值的附加对象),那么最好还是使用简单的空检查和三元运算符

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

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

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

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

每当我想到为特定目的使用可选API时,我总是提醒自己它的目的是什么,以及它为什么被引入JDK,也就是说

中的可选选项旨在为库方法提供有限的机制 明确需要表示“无结果”的返回类型,以及 在这里使用null极有可能导致错误-Stuart Marks

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

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

我会让事情变得简单,而是做:

String hi = sayHi();
if(hi == null) hi = “-“;
...
在方法调用中使用
是可选的吗

,这是个坏习惯。其基本思想是表示没有返回值,而不是包装可能为
null的所有内容。我强烈反对这种用法

或者只是额外的冗长编码

在我看来,这似乎是一个失败的尝试,使您的代码更时尚。(“看,我们正在使用全新的
Optional
fromJava8!”)

我更喜欢可读性和清晰性,而不是简洁性

这种
可选的
用法并不清晰,但会引发以下问题:

为什么要包装变量?
您将如何处理此
可选

是否会在下面使用/退回

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

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

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

String hi = (hi = sayHi()) != null ? hi : "-";
不过,你的两行建议绝对不错:

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

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

在我看来,只返回一个
可选的
,让调用者处理一个缺少的值会更有意义

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

另一方面,您的操作符似乎足够简洁,如果一直使用,它可能是实用的


我不认为性能是一个大问题。

简而言之:避免使用
可选类型。
返回类型的
可选
的主要参数是,“客户很容易忘记处理返回值为空的可能性
Optional
在您的脸上很难看,因此客户不太可能忘记处理返回值为空的可能性。在其他任何地方,程序员都应该继续使用正常引用,这可能是空的。”


我写了一篇关于使用Java的
可选
类型的利弊的讨论。在JDK 9或更高版本中,使用以下内容:

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

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

感谢您对
对象的建议。toString
。这对于字符串来说似乎确实更好。我没有控制对另一个注释中调用的方法进行rol,因此我不能返回
Optional
。Elvis将非常方便。@chrylis同意,因为我是它的粉丝,但其他人认为将它集成到语言中并没有那么重要…来自C,这归结为字符串hi=sayHi()-“这在我看来是一个进步。加上引用我的话:”——“事实上,布莱恩·戈茨提出了最初的措词,他和我用文字进行了修改。@StuartMarks确实很高兴,谢谢你纠正我。