Java 8 streams, why does this compile part 2… Or what is a method reference, really?

孤街浪徒 提交于 2019-12-03 00:12:35
assylias

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

Primary :: [TypeArguments] Identifier

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

From the State of Lambda

Kinds of method references

There are several different kinds of method references, each with slightly different syntax:

  • A static method (ClassName::methName)
  • An instance method of a particular object (instanceRef::methName)
  • A super method of a particular object (super::methName)
  • An instance method of an arbitrary object of a particular type (ClassName::methName)
  • A class constructor reference (ClassName::new)
  • An array constructor reference (TypeName[]::new)

Saying this:

something(new Main()::meh);

Is approximately equivalent to saying this:

Main x = new Main();
something(() -> x.meh());

Or this:

final Main x = new Main();
something(new Whatever() {
    public void meh(Integer ignored) {
        x.meh();
    }
}

The new instance is "captured" and used in the new lambda instance which was implicitly created from the method handle.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!