好的,这个“系列”的第一个问题是
this one.
@H_403_23@解决方法
现在,这里还有另一种情况:
Arrays.asList("hello","world").stream().forEach(System.out::println);
这个编译和工作…
好的,在最后一个问题中,使用静态方法从一个类.
但现在这是不同的:System.out是System的静态字段,是的;它也是一个PrintStream,PrintStream有一个println()方法,它恰好匹配了这种情况下的消费者的签名和a Consumer
is what forEach()
expects.
所以我试过这个
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"); } }
它的工作原理
这是相当不同的范围,因为我启动一个新的实例,并可以在构造这个实例之后使用方法引用!
那么,是一个方法参考真正的任何方法来遵守签名?有什么限制?有没有人可以建立一个不能在@FunctionalInterface中使用的“@FunctionalInterface兼容”方法?
方法引用的语法在
JLS #15.13中定义.特别地,它可以是以下形式:
Primary :: [TypeArguments] Identifier
哪里Primary
can be,among other things, 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