为什么 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>
...
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>
...