Java 8流,为什么要编译第2部分......或者什么是方法参考,真的吗? [英] Java 8 streams, why does this compile part 2... Or what is a method reference, really?

查看:113
本文介绍了Java 8流,为什么要编译第2部分......或者什么是方法参考,真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这个系列中的第一个问题是这一个

OK, the first question in this "series" was this one.

现在,这是另一种情况:

Now, here is another case:

Arrays.asList("hello", "world").stream().forEach(System.out::println);

这个编译,并且有效......

This compiles, and works...

好的,在上一个问题中,使用了来自的静态方法。

OK, in the last question, static methods from a class were used.

但现在这是不同的: System.out 系统静态字段,是;它也是一个 PrintStream ,而一个 PrintStream 有一个 println()在这种情况下恰好匹配 Consumer 的签名的方法,以及 a Consumer 是什么 forEach()期望

But now this is different: System.out is a static field of System, yes; it is also a PrintStream, and a PrintStream has a println() method which happens to match the signature of a Consumer in this case, and a Consumer is what forEach() expects.

所以我试过了......

So I tried this...

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");
    }
}

它有效!

这是一个完全不同的范围,因为我发起了一个新实例,并且可以在构造这个实例后立即使用方法引用!

This is quite a different scope here, since I initiate a new instance and can use a method reference right after this instance is constructed!

那么,是一个方法参考真的任何方法服从签名吗?有什么限制?有没有人可以建立一个@FunctionalInterface兼容的方法不能 c> @FunctionalInterface ?

So, is a method reference really any method which obeys the signature? What are the limits? Are there any cases where one can build a "@FunctionalInterface compatible" method which cannot be used in a @FunctionalInterface?

推荐答案

方法引用的语法在 JLS#15.13 。特别是它可以是以下形式:

The syntax of method references is defined in JLS #15.13. In particular it can be of the form:


Primary :: [TypeArguments] Identifier

其中 主要可以是 a:

Where Primary can be, among other things, a:


ClassInstanceCreationExpression

所以是的,你的语法是正确的。其他一些有趣的例子:

so yes, your syntax is correct. A few other interesting examples:

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(...)

顺便说一下,既然提到了静态方法,那么有趣的是,您无法从实例创建静态方法引用:

By the way, since you mention static methods, it is interesting to note that you can't create a static method reference from an instance:

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

这篇关于Java 8流,为什么要编译第2部分......或者什么是方法参考,真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆