3 回答
TA贡献1802条经验 获得超10个赞
我从 Stuart Marks 本人那里找到了背后的原因
http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-October/044026.html
这与嵌套泛型(Optional嵌套在内部Function)有关。从邮件线程
Function<..., Optional<StringBuilder>>不是的子类型
Function<..., Optional<? extends CharSequence>>为了解决这个问题,我们还必须添加外部通配符,这样
Function<..., Optional<StringBuilder>>是一个子类型
Function<..., ? extends Optional<? extends CharSequence>>
TA贡献1853条经验 获得超9个赞
FWIW,在 Java 11 中的Stream.iterate和Stream.iterate中仍然存在与协变参数类似的问题。当前的方法签名是
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
这些签名不允许某些UnaryOperator从类型角度来看合理的种子和 s 组合,例如,以下内容无法编译:
UnaryOperator<String> op = s -> s;
Stream<CharSequence> scs = iterate("", op); // error
建议的解决方案是将方法签名更改为
static <T, S extends T> Stream<T> iterate(S seed, Predicate<? super S> hasNext, UnaryOperator<S> next)
static <T, S extends T> Stream<T> iterate(S seed, UnaryOperator<S> f)
因此,与Optional.or和Optional.flatMap相比, 这是“附加类型参数方法”实际起作用的情况。
TA贡献1921条经验 获得超9个赞
是的...据说带有extends-bound(上限)的通配符使类型 covariant,这意味着例如List<Apple>是List<? extends Fruit>(考虑到Appleextends Fruit)的实际子类型;这也称为协方差。
或者在您展示的示例中,这意味着它Optional<StringBuilder>是 的子类型Optional<? extends Optional<? extends CharSequence>>,因此您可以例如执行以下操作:
List<Optional<String>> left = new ArrayList<>();
List<? extends Optional<? extends CharSequence>> right = new ArrayList<>();
right = left; // will compile
或分配Function给另一个
添加回答
举报
