2

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?

9
  • 4
    You can't - it doesn't fit the functional interface. What would you expect the value of the abc parameter to be within testStatic? In the lambda expression you're passing in str, which makes perfect sense. You could create an adapter between the two different method signatures (create two functional interfaces, and an adapter which called one based on the other and an extra parameter). Commented Apr 11, 2014 at 22:29
  • 1
    They didn't devise a syntax for this. And it doesn't seem worth adding complexity to the language for it. If you want the ability to type something like DemoStatic::testStatic(str), that's really only a couple keystrokes less than the lambda expression. Commented Apr 11, 2014 at 22:35
  • 2
    Java does not support currying without a wrapper method/lambda. Commented Apr 11, 2014 at 22:37
  • 1
    Remember, a lambda expression is not the same a method reference. Commented Apr 11, 2014 at 22:38
  • 2
    @KishanSarsechaGajjar: It's a perfectly good functional interface - but it's got to be implemented by a method with a suitable signature. Commented Apr 11, 2014 at 22:40

1 Answer 1

11

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:

Four Types 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!
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.