我正在使用Java 1.8.0_151,有些代码无法编译,我不明白:
Optional optional = Optional.of("dummy");
Optional<Boolean> result1 = optional.map(obj -> true); // works fine
boolean result2 = result1.orElse(false); // works fine
boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object
Object result4 = optional.map(obj -> true).orElse(false); // works fine
为什么它在result1
上正常工作但在result3
上出现编译错误?
其他信息:
Optional
更改为Optional<String>
时,result3也可以编译result3
分成两行时:result1
和result2
,result3
能够编译答案 0 :(得分:9)
一旦你失去了类型安全性 - 它也会因链式通话而丢失。那是Optional<Object> != Optional
。所以当你这样做时
Optional optional = Optional.of("dummy");
optional.map()
map
只能接受原始Function
而不接受任何其他内容,这显然会返回Object
。
正确的方法是添加类型信息:
Optional<String> optional = Optional.of("dummy");
或者你可以不安全地投射:
boolean result3 = (boolean) optional.map(obj -> true).orElse(false)
答案 1 :(得分:4)
optional
是原始Optional
,因此optional.map(obj -> true)
返回原始Optional
,而orElse(false)
返回Object
,而不是Boolean
1}}。编译器不知道如何取消Object
到boolean
。
通过更改
Optional optional = Optional.of("dummy");
到
Optional<Object> optional = Optional.of("dummy");
或
Optional<String> optional = Optional.of("dummy");
您将克服此错误,因为现在optional.map(obj -> true)
将返回Optional<Boolean>
而orElse(false)
将返回Boolean
。
答案 2 :(得分:0)
感谢您的回答。我只是想详细介绍一下它在resutl1
上的工作原理,而不是result3
:
Optional<Boolean> result1 = optional.map(obj -> true); // works fine
boolean result2 = result1.orElse(false); // works fine
boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object
<{1>} result1
上的optional
变量是原始类型,因此optional.map(obj -> true)
返回了Optional
原始类型。
当我宣布Optional<Boolean> result1
时,Optional
原始类型自动投放到Optional<Boolean>
另一方面,optional.map(obj -> true).orElse(false);
失败,因为原始类型Optional
对象无法调用.orElse(false)
原始类型的此行为的另一个示例是:
List li = new ArrayList<String>();
List<String> li1 = li;
List<Integer> li2 = li;
List<Map> li3 = li;
li1.add("WWW");
li2.add(444);
li3.add(new HashMap());
适用于所有场景,li
对象将包含String,Integer和HashMap()。 li1, li2, li3
被自动转换为非原始类型。