-->

How to invoke parameterized method with method ref

2019-05-18 10:00发布

问题:

Consider below code,

interface TestInter {
    public void abc();
}


class DemoStatic {

    public static void testStatic(String abc) {
        System.out.println(abc);
    }

    public void runTest () {

        // Using lambda expression.
        String str = "demo string" ;
        TestInter demo1 = () -> DemoStatic.testStatic(str);
        demo1.abc();

        // Using method reference.
        TestInter demo2 = DemoStatic::testStatic; // This line is not compiling.
        demo2.abc();
    }
}

We can invoke the testStatic method as body of TestInter interface's abc() implementation if parameter of testStaic() method will be eliminated as described in this so answer.

But in this case how can we write method reference for parameterized method testStatic?

回答1:

Your functional interface TestInter does not have corresponding signature for your testStatic(String) method. If you want to refer to testStatic() using the :: notation, you should add the parameter:

interface TestInter2 {
    public void abc(String abc);
}

public void runTest () {
    TestInter2 demo2 = DemoStatic::testStatic;
    demo2.abc(str);
}

According to Oracle Java tutorial, there are four kinds of method reference:

I prepared 3 interfaces - for 0, 1 and 2 parameters. Then we have 3 static and 3 instance methods:

interface F0 {
    void f0();
}
interface F1 {
    void f1(MetRef i1);
}
interface F2 {
    void f2(MetRef i1, MetRef i2);
}

public class MetRef {
    public static void stat0() {;}
    public static void stat1(MetRef a) {;}
    public static void stat2(MetRef a, MetRef b) {;}

    public void inst0() {;}
    public void inst1(MetRef a) {;}
    public void inst2(MetRef a, MetRef b) {;}
}

Now look how each of the methods may be used as a method reference in various combinations, compare them with the previous table. See different method reference types in action and notice from where the parameters come.

public class Test {
    public static void main(String[] args) {
        final MetRef mr = new MetRef();

        final F0 mr01 = MetRef::stat0; // 1: f0() ~ MetRef.stat0() 
        final F0 mr02 = mr::inst0;     // 2: f0() ~ mr.inst0()
        final F0 mr04 = MetRef::new;   // 4: f0() ~ new MetRef()

        final F1 mr11 = MetRef::stat1; // 1: f1(i1) ~ MetRef.stat1(i1)
        final F1 mr12 = mr::inst1;     // 2: f1(i1) ~ mr.inst1(i1)
        final F1 mr13 = MetRef::inst0; // 3: f1(i1) ~ i1.inst0()       <== NOTICE!

        final F2 mr21 = MetRef::stat2; // 1: f2(i1, i2) ~ MetRef.stat2(i1, i2)
        final F2 mr22 = mr::inst2;     // 2: f2(i1, i2) ~ mr.inst2(i1, i2)
        final F2 mr23 = MetRef::inst1; // 3: f2(i1, i2) ~ i1.inst1(i2) <== NOTICE!
    }
}