Java8流,为什么要编译第2部分。。。或者什么是方法引用,真的?
好的,这个“系列”的第一个问题是 下面是另一个例子:Java8流,为什么要编译第2部分。。。或者什么是方法引用,真的?,java,java-8,functional-interface,Java,Java 8,Functional Interface,好的,这个“系列”的第一个问题是 下面是另一个例子: Arrays.asList("hello", "world").stream().forEach(System.out::println); 这是编译的,并且有效 好的,在最后一个问题中,使用了类中的静态方法 但现在不同了:System.out是System的静态字段,是的;它也是一个PrintStream,PrintStream有一个println()方法,在这种情况下,该方法恰好与消费者的签名相匹配,并且 所以我试过这个 public
Arrays.asList("hello", "world").stream().forEach(System.out::println);
这是编译的,并且有效
好的,在最后一个问题中,使用了类中的静态方法
但现在不同了:System.out
是System
的静态
字段,是的;它也是一个PrintStream
,PrintStream
有一个println()
方法,在这种情况下,该方法恰好与消费者的签名相匹配,并且
所以我试过这个
public final class Main
{
public static void main(final String... args)
{
Arrays.asList(23, 2389, 19).stream().forEach(new Main()::meh);
}
// Matches the signature of a Consumer<? super Integer>...
public void meh(final Integer ignored)
{
System.out.println("meh");
}
}
公共最终类主
{
公共静态void main(最终字符串…参数)
{
Arrays.asList(232389,19).stream().forEach(newmain()::meh);
}
//匹配消费者的签名,上面写着:
something(new Main()::meh);
Main x = new Main();
something(() -> x.meh());
大致相当于这样说:
something(new Main()::meh);
Main x = new Main();
something(() -> x.meh());
或者这个:
final Main x = new Main();
something(new Whatever() {
public void meh(Integer ignored) {
x.meh();
}
}
新实例被“捕获”并用于从方法句柄隐式创建的新lambda实例。
各种方法引用
有几种不同类型的方法引用,每种都有
语法略有不同:
- 静态方法(
ClassName::methName
)
- 特定对象的实例方法(
instanceRef::methName
)
- 特定对象的超级方法(
super::methName
)
- 特定类型的任意对象的实例方法(
ClassName::methName
)
- 类构造函数引用(
ClassName::new
)
- 数组构造函数引用(
TypeName[]::new
)
方法引用的语法在中定义。具体而言,它可以是以下形式:
Primary::[TypeArguments]标识符
其中a:
ClassInstanceCreationExpression
是的,你的语法是正确的。还有几个有趣的例子:
this::someInstanceMethod // (...) -> this.someInstanceMethod(...)
"123"::equals // (s) -> "123".equals(s)
(b ? "123" : "456")::equals // where b is a boolean
array[1]::length // (String[] array) -> array[1].length()
String[]::new // i -> new String[i]
a.b()::c // (...) -> a.b().c(...)
顺便说一下,既然您提到了静态方法,那么有意思的是,您不能从实例创建静态方法引用:
class Static { static void m() {} }
Static s = new Static();
s.m(); //compiles
someStream.forEach(s::m); //does not compile
someStream.forEach(Static::m); //that's ok
你真的应该阅读第8节:方法引用开始的部分。这并不奇怪,因为你可以做newmain()。meh(42)
应该使用“奖励现有答案”赏金理由,而不是“吸引注意”。不过没什么大不了的。看起来我有很多东西要学……谢谢你的详细答案!