Java 8 - 通用供应商

时间:2015-03-17 14:38:32

标签: java-8 type-erasure

今天我尝试了reference泛型构造函数。为什么不正确?

import java.util.Collection;
import java.util.function.Supplier;

class Foo<R extends Collection<Integer>> {
    Supplier<R> supplier = R::new;  // Compiler error!
}

错误文字:

java: unexpected type
  required: class or array
  found:    type parameter R

是因为type erasure吗?或许我做错了?

1 个答案:

答案 0 :(得分:8)

在编译时,你所知道的R就是它的界限;它是Collection<Integer>的子类型。你不知道哪个班级R对应。但是你试图引用一个构造函数 - 并且要引用一个构造函数,你必须确切地知道你正在尝试构造什么类。由于同样的原因,以下所有内容都无法工作:不知道R是什么,并且您需要知道R是什么来调用它的构造函数。

Supplier<R> supplier = R::new
Supplier<R> supplier = () -> new R();
R r = new R();

即使R被声明为<R extends ArrayList<String>>,情况也是如此。在这种情况下,您知道R延伸ArrayList<String>,但您仍然不知道它是什么类!

如果您尝试访问Collection<Integer>的虚拟成员,则可以使用:

ToIntFunction<R> sizer = R::size;

因为,无论R是什么,它都必须有size()方法。