【发布时间】:2018-05-26 00:42:54
【问题描述】:
我一直在做一些 Java Streams 操作,当然它不喜欢我的代码并且拒绝提供有用的错误消息。 (作为参考,我对 C# 和 Linq 没有任何问题,所以我从概念上理解我正在尝试做的一切。)所以我开始深入研究将显式泛型类型添加到我的代码中的每个方法,这样我就可以找到源代码问题,因为过去的经验告诉我,这是一条成功的前进道路。
在环顾四周时,我遇到了一些我不明白的东西。考虑 Java 源代码中的以下代码(稍微重新格式化):
public static <T> Collector<T, ?, List<T>> toList() {
return new Collectors.CollectorImpl<>(
(Supplier<List<T>>) ArrayList::new,
List::add,
(left, right) -> {
left.addAll(right);
return left;
},
Collectors.CH_ID
);
}
为什么toList 方法签名在其返回类型中需要通配符??当我删除它时,我得到了
Wrong number of type arguments: 2; required: 3
和
Incompatible types. Required: Collector<T, List<T>, > Found: CollectorImpl<java.lang.Object, List<T>, java.lang.Object>
当我将? 更改为Object 时,我得到(参考上述代码中的这些行/方法):
List::add – Cannot resolve method 'add' left.addAll – Cannot resolve method 'addAll(java.lang.Object)'
当我放回通配符并检查这两个时,它们是:
List – public abstract boolean add(T e) List – public abstract boolean addAll(Collection<? extends T> c)
进一步摆弄并没有教会我更多东西。
我了解在? extends T 等一种情况下,Java 中的通配符可以转换为带有where TWildCard : T 的新泛型类型参数的C#。但是上面的toList 是怎么回事,返回类型有一个裸通配符?
【问题讨论】:
-
澄清一下,你问的是返回类型
Collector<T, ?, List<T>>中的通配符,对吧? -
@Radiodef 正确。澄清。
-
很好的问题,直到现在才考虑