在构造函数方法引用中,使用泛型类型参数与不使用泛型类型参数之间的区别?



我正在阅读Effective Java 3,并在第43项中注意到以下代码:"首选方法引用而不是lambdas":

TreeMap<K,V>::new

请注意类型参数。我总是做:

TreeMap::new

我使用 Intellij,但从未收到有关此警告或任何更改它的建议。实际上,当我让IDE将上述方法引用更改为lambda时,它会将其转换为

() -> new TreeMap<Integer, Integer>()

包含类型参数的价值是什么?编译器不能根据变量的类型参数推断出来吗?根据 IDE 如何将方法引用转换为 lambda,它似乎可以。

构造函数引用TreeMap::new与使用 菱形类型推断 (§15.13.1) 相同:

为方便起见,当泛型类型的名称用于引用实例方法(其中接收器成为第一个参数)时,目标类型用于确定类型参数。这有利于用Pair::first代替Pair<String,Integer>::first

同样,像Pair::new这样的方法引用被视为"菱形"实例创建(new Pair<>())。由于"菱形"是隐式的,因此此窗体不会实例化原始类型;实际上,无法表示对原始类型的构造函数的引用。

您需要在或多或少与需要向构造函数显式提供类型参数时相同的情况下显式提供类型参数。

例如,在下文中,对get的调用阻止在推理supplier期间考虑返回分配,因此推断TArrayList<Object>

class Example {
public static void main(String[] args) {
ArrayList<String> list =
supplier(ArrayList::new).get(); // compile error
}
static <T> Supplier<T> supplier(Supplier<T> s) { return s; }
}

在那个人为的例子中,我们必须使用ArrayList<String>::new.

最新更新