Optional<ArrayList<String>> option = Optional.of(new ArrayList<>());
Optional<ArrayList<?>> doesntWork = option;
Optional<ArrayList<?>> works = option.map(list -> list);
第一个尝试的赋值不会编译,但是第二个带有map
的赋值会编译。感觉map
实际上不应该做任何事情,但是由于某种原因,它使我的Optional<ArrayList<String>>
变成了Optional<ArrayList<?>>
。是否存在某种隐式强制转换?
答案 0 :(得分:25)
如果您查看map
的代码并遵循所有方法调用,您会看到option.map(list -> list)
最终返回了new Optional<>(option.get())
。因此,您可以将您的上一个作业替换为:
Optional<ArrayList<?>> works = new Optional<>(option.get());
这将创建一个新的Optional<ArrayList<?>>
并使用value
返回的ArrayList<?>
初始化其ArrayList<String>
实例变量(类型为map.get()
)。这是有效的分配。
是否存在某种隐式强制转换?
否,map
返回一个新的Optional
实例。它不会转换调用它的原始实例。
这是方法调用的链:
option.map(list -> list)
返回(因为option
不为空)
Optional.ofNullable(mapper.apply(value))
与您的情况相同
Optional.ofNullable(value)
返回(因为值不为空):
Optional.of(value)
返回
new Optional<>(value)
答案 1 :(得分:10)
第一个不起作用,因为泛型是不变的,使它们协变的唯一方法是添加一个有界类型,例如:
Optional<? extends ArrayList<String>> doesntWork = option;
可以编译。
并且当您说map
步骤不应该完成任何事情时,这是不正确的。查看Optional::map
的定义:
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
粗略地说,它是从Optional<T>
转换为Optional<U>
...
答案 2 :(得分:0)
您的option.map
具有签名
<ArrayList<?>> Optional<ArrayList<?>> java.util.Optional.map(Function<? super ArrayList<String>, ? extends ArrayList<?>> mapper)
所以这个
Optional<? extends ArrayList<?>> doesntWork = option;
可以编译。
答案 3 :(得分:0)
在后一种情况下,Optional.map
方法的返回类型由works
变量的类型隐式确定。这就是为什么存在差异的原因。