好的,这个“系列”中的第一个问题是this one https://stackoverflow.com/questions/22561614/java-8-streams-min-and-max-why-does-this-compile.
现在,这是另一个案例:
Arrays.asList("hello", "world").stream().forEach(System.out::println);
这可以编译并运行...
好的,在最后一个问题中,来自 a 的静态方法class被使用。
但现在情况不同了:System.out
is a static
现场System
, 是的;它也是一个PrintStream
, and a PrintStream
has a println()
恰好与 a 的签名匹配的方法Consumer
在这种情况下,并且a Consumer是什么forEach() expects http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#forEach-java.util.function.Consumer-.
所以我尝试了这个...
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");
}
}
它有效!
这是一个完全不同的范围,因为我启动了一个新实例,并且可以在构造该实例后立即使用方法引用!
那么,方法参考真的吗?any遵循签名的方法?有什么限制?是否存在可以构建“@FunctionalInterface 兼容”方法的情况cannot被用在一个@FunctionalInterface
?
方法引用的语法定义在JLS #15.13 http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13。特别地,它可以是以下形式:
Primary :: [TypeArguments] Identifier
Where Primary除其他外,可以是 http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-Primary 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)