Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8流,为什么要编译第2部分。。。或者什么是方法引用,真的?_Java_Java 8_Functional Interface - Fatal编程技术网

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)
应该使用“奖励现有答案”赏金理由,而不是“吸引注意”。不过没什么大不了的。看起来我有很多东西要学……谢谢你的详细答案!