指定 before/after :: 运算符的通用方法引用类型
Generic method reference type specifying before/after :: operator
下面的方法引用有什么区别,
BiPredicate<List<String>,String> contains1 = List<String>::contains;
BiPredicate<List<String>,String> contains2 = List::<String>contains;
BiPredicate<List<String>,String> contains3 = List<String>::<String>contains;
案例有特殊名称吗?有类似用法的例子吗?
以下是 Intellij 告诉我的关于它们的内容:
BiPredicate<List<String>, String> contains1 = List<String>::contains;
Explicit type arguments can be inferred
BiPredicate<List<String>, String> contains2 = List::<String>contains;
Type arguments are redundant for the non-generic method reference
如果将它们拆分为各自的 lambda 函数,我相信您会看到以下内容:
BiPredicate<List<String>, String> contains1 = (List<String> strings, String o) -> strings.contains(o);
BiPredicate<List<String>, String> contains2 = (strings, o) -> strings.<String>contains(o);
我们知道,(List<String> strings, String o)
可以用 (strings, o)
代替,第二行的 <String>
是不需要的(因为 String#contains
不是通用的),所以它是可以安全地假设两个方法引用是等价的。
首先,这被称为 type witness (in the official Oracle Tutorial) or TypeArguments (in the JLS Sec 15.12),您正在有效地帮助编译器进行此类构造。
一个例子:
private static void test(Callable<Object> call) {
}
private static void test(Runnable run) {
}
static class Gen<T> {
}
并通过 test(Gen::new);
调用它(这会失败,不管为什么),但关键是你添加了一个 type witness 来帮助编译器,所以这会起作用
test(Gen<String>::new);
因此,当您编写 List<String>
时,您已经为目标类型添加了类型见证 - List
即;在第二种情况下,您要为方法 contains
添加一个 - 但它不是通用的,因此将被忽略。
在:
BiPredicate<List<String>, String> contains2 = List::<String>contains;
<String>
是非泛型 List.contains
方法 1 的类型参数。
同时在:
BiPredicate<List<String>, String> contains1 = List<String>::contains;
<String>
是 List
.
的类型参数
1 - 在这种特殊情况下,根据 JLS §15.12.2.1:
忽略类型参数
A non-generic method may be potentially applicable to an invocation
that supplies explicit type arguments. In such a case, the type
arguments will simply be ignored.
下面的方法引用有什么区别,
BiPredicate<List<String>,String> contains1 = List<String>::contains;
BiPredicate<List<String>,String> contains2 = List::<String>contains;
BiPredicate<List<String>,String> contains3 = List<String>::<String>contains;
案例有特殊名称吗?有类似用法的例子吗?
以下是 Intellij 告诉我的关于它们的内容:
BiPredicate<List<String>, String> contains1 = List<String>::contains;
Explicit type arguments can be inferred
BiPredicate<List<String>, String> contains2 = List::<String>contains;
Type arguments are redundant for the non-generic method reference
如果将它们拆分为各自的 lambda 函数,我相信您会看到以下内容:
BiPredicate<List<String>, String> contains1 = (List<String> strings, String o) -> strings.contains(o);
BiPredicate<List<String>, String> contains2 = (strings, o) -> strings.<String>contains(o);
我们知道,(List<String> strings, String o)
可以用 (strings, o)
代替,第二行的 <String>
是不需要的(因为 String#contains
不是通用的),所以它是可以安全地假设两个方法引用是等价的。
首先,这被称为 type witness (in the official Oracle Tutorial) or TypeArguments (in the JLS Sec 15.12),您正在有效地帮助编译器进行此类构造。
一个例子:
private static void test(Callable<Object> call) {
}
private static void test(Runnable run) {
}
static class Gen<T> {
}
并通过 test(Gen::new);
调用它(这会失败,不管为什么),但关键是你添加了一个 type witness 来帮助编译器,所以这会起作用
test(Gen<String>::new);
因此,当您编写 List<String>
时,您已经为目标类型添加了类型见证 - List
即;在第二种情况下,您要为方法 contains
添加一个 - 但它不是通用的,因此将被忽略。
在:
BiPredicate<List<String>, String> contains2 = List::<String>contains;
<String>
是非泛型 List.contains
方法 1 的类型参数。
同时在:
BiPredicate<List<String>, String> contains1 = List<String>::contains;
<String>
是 List
.
1 - 在这种特殊情况下,根据 JLS §15.12.2.1:
忽略类型参数A non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. In such a case, the type arguments will simply be ignored.