想象一个Optional.ofNullable
支票分配给一个String
:
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult);
getResult
返回String
的地方。
虽然我知道它不能编译,但我可以通过添加toString()
或.orElse("");
进行排序来修复它。
就目前而言,错误是:
方法参考中的返回类型错误,无法转换java.lang.String 到
我了解添加orElse("")
是因为这会将result
分配给空的String
。
但是,如果一路上有toString()
,那么添加null
有什么好处?还是仅仅是为了使其能够编译?
答案 0 :(得分:2)
map
的返回类型为Optional <U>
,因此,要获取真实值,应使用返回类型为orElse
的{{1}}来调用。
如果T
,则这是toString
的实现:
Optional
因此,调用@Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
永远不会获得真实值,而是包装到toString
的值,而Optional
将返回您提供的默认值。
让我们来看看区别:
orElse
输出:
Integer i = 4;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
使用Optional[4]
:
null
输出:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
使用Optional.empty
时:
orElse
输出:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
因此您可以看到这些方法有不同的用途。
以及您评论的答案:
“ 有没有办法在同一链中调用get()并同时调用orElse()?”
None
输出:
Integer i = 10;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
您不需要显式调用10
,如果不是get
,则将获取该值;
null
答案 1 :(得分:1)
如果您希望result
为null,而途中某事返回null,则执行orElse(null)
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult).orElse(null);
答案 2 :(得分:1)
我了解添加orElse(“”),因为这会将结果分配为空 字符串。
这听起来不像您对我理解的那样,因为这不是正在发生的事情的好描述。 Optional.orElse
执行以下操作:如果可选包含值,则返回该值。如果它不包含值,则返回您提供的任何参数。
从语义上讲,它等同于以下内容:
if (optional.ifPresent())
{
return optional.get();
}
else
{
return theArgument;
}
调用toString
虽然可以满足编译器的要求,但不是。您正在将Optional
对象本身转换为字符串,而不是从内部获取字符串!尽管您的字符串将被包含,但这仅是因为JDK开发人员决定如何实现toString
。他们同样可能没有提供实现,而只剩下just the default behaviour。
在日志记录之外,永远不应依赖在toString
上调用Optional
。从本质上讲,它只是调试信息。如果执行此操作,则还将打印有关Optional
包装器的信息,这几乎肯定不是您想要的。
System.out.println(Optional.empty()); // Optional.empty
System.out.println(Optional.of("foo")); // Optional[foo]