为什么 Optional.map 让这个作业生效?

Why does Optional.map make this assignment work?

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<?>>。是否正在进行某种隐式转换?

你的option.map有签名

<ArrayList<?>> Optional<ArrayList<?>> java.util.Optional.map(Function<? super ArrayList<String>, ? extends ArrayList<?>> mapper)

所以这个

Optional<? extends ArrayList<?>> doesntWork = option;

编译。

在后一种情况下,Optional.map 方法的 return 类型由 works 变量的类型隐式确定。这就是为什么会有差异。

如果您查看 map 的代码并跟踪所有方法调用,您会发现 option.map(list -> list) 最终返回 new Optional<>(option.get())。因此,您可以将上次作业替换为:

Optional<ArrayList<?>> works = new Optional<>(option.get());

这将创建一个新的 Optional<ArrayList<?>> 并使用 map.get() 返回的 ArrayList<String> 初始化其 value 实例变量(其类型为 ArrayList<?>)。这是一个有效的分配。

Is there some sort of implicit cast going on?

不,map returns 一个新的 Optional 实例。它不会转换调用它的原始实例。

这是方法调用链:

option.map(list -> list)

returns(因为 option 不为空)

Optional.ofNullable(mapper.apply(value))

你的情况与

相同
Optional.ofNullable(value)

which returns(因为值不为空):

Optional.of(value)

哪个returns

new Optional<>(value)

好吧,第一个不起作用,因为泛型是不变的,使它们协变的唯一方法是添加一个有界类型,例如:

 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>...