在构造方法引用中,使用泛型类型参数和不使用泛型类型参数的区别?
In constructor method references, difference between using generic type parameters and not?
我正在阅读 Effective Java 3 并注意到项目 43 中的这段代码:“首选对 lambda 的方法引用”:
TreeMap<K,V>::new
注意类型参数。我总是刚刚完成:
TreeMap::new
我使用 Intellij 并且从未收到过关于此的警告或任何更改它的建议。事实上,当我将 IDE 将上述方法引用更改为 lambda 时,它会将其转换为
() -> new TreeMap<Integer, Integer>()
包含类型参数的价值是什么?编译器不能根据变量的类型参数推断出来吗?基于 IDE 如何将方法引用转换为 lambda,它似乎可以。
构造函数引用TreeMap::new
与使用菱形类型推断相同(§15.13.1):
For convenience, when the name of a generic type is used to refer to an instance method (where the receiver becomes the first parameter), the target type is used to determine the type arguments. This facilitates usage like Pair::first
in place of Pair<String,Integer>::first
.
Similarly, a method reference like Pair::new
is treated like a "diamond" instance creation (new Pair<>())
. Because the "diamond" is implicit, this form does not instantiate a raw type; in fact, there is no way to express a reference to the constructor of a raw type.
您需要显式提供类型参数的情况与您需要显式向构造函数提供类型参数的情况大致相同。
例如,在下文中,对 get
的调用阻止 return 赋值在 supplier
的推理过程中被考虑,因此 T
被推断为ArrayList<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
。
我正在阅读 Effective Java 3 并注意到项目 43 中的这段代码:“首选对 lambda 的方法引用”:
TreeMap<K,V>::new
注意类型参数。我总是刚刚完成:
TreeMap::new
我使用 Intellij 并且从未收到过关于此的警告或任何更改它的建议。事实上,当我将 IDE 将上述方法引用更改为 lambda 时,它会将其转换为
() -> new TreeMap<Integer, Integer>()
包含类型参数的价值是什么?编译器不能根据变量的类型参数推断出来吗?基于 IDE 如何将方法引用转换为 lambda,它似乎可以。
构造函数引用TreeMap::new
与使用菱形类型推断相同(§15.13.1):
For convenience, when the name of a generic type is used to refer to an instance method (where the receiver becomes the first parameter), the target type is used to determine the type arguments. This facilitates usage like
Pair::first
in place ofPair<String,Integer>::first
.Similarly, a method reference like
Pair::new
is treated like a "diamond" instance creation(new Pair<>())
. Because the "diamond" is implicit, this form does not instantiate a raw type; in fact, there is no way to express a reference to the constructor of a raw type.
您需要显式提供类型参数的情况与您需要显式向构造函数提供类型参数的情况大致相同。
例如,在下文中,对 get
的调用阻止 return 赋值在 supplier
的推理过程中被考虑,因此 T
被推断为ArrayList<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
。