泛型 - ?使用

paw*_*pta 3 java generics

java.util.Stream接口的JDK文档具有以下代码片段作为收集器构造的示例.

Collector<Widget, ?, TreeSet<Widget>> intoSet =
         Collector.of(TreeSet::new, TreeSet::add,
                      (left, right) -> { left.addAll(right); return left; });
Run Code Online (Sandbox Code Playgroud)

Collector.of方法的返回类型为 static <T,R> Collector<T,R,R>

是吗?在示例中的返回类型中,只是一种方便的方式来引用下一个泛型类型,因为这两个类型在方法签名中已声明为相同.并且以下三个陈述都是同一个:

Collector<Widget, ?, TreeSet<Widget>> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
Collector<Widget, TreeSet<Widget>, TreeSet<Widget>> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
Collector<Widget, TreeSet<Widget>, ?> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
Run Code Online (Sandbox Code Playgroud)

Nic*_*tto 6

什么是wildcard

在通用代码中,?名为()的问号()wildcard表示未知类型.通配符可用于各种情况:作为参数,字段或局部变量的类型; 有时作为返回类型(虽然更好的编程实践更具体).通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数.

为什么用它Collector.of

正如你已经注意到了Collector.of(Supplier<R> supplier, BiConsumer<R, T> accumulator, BinaryOperator<R> combiner, Characteristics... characteristics)回报类型的对象Collector<T, R, R>明知类Collector有3个类型的参数,这些参数T,A并且R其中:

  • <T>:缩减操作的输入元素的类型.
  • <A>:还原操作的可变累积类型(通常隐藏为实现细节)
  • <R>:缩减操作的结果类型

因此,如javadoc中所述,我们通常对类型参数使用通配符,<A>因为它被视为实现细节,因为它只是一个中间类型,真正重要的是输入和输出类型参数T,R因此为了简单起见/可读性?优于理论上应该使用的,TreeSet<Widget>在这种情况下.