Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Method reference to instance method of an arbitrary object of a particular type

Why does the following not work?

import java.util.function.Function;

public class MethodRefTest {
   public String passMeAround( String input ) {
      return input + " been passed to me";
   }

   public Function<String, String> testReferences() {
      final Function<String, String> f1 = MethodRefTest::passMeAround;
      return f1;
   }

   public static void main( String[] args ) {
      new MethodRefTest()
            .testReferences()
            .apply( "foo" );
   }
}

Javac tells me:

MethodRefTest.java:14: error: invalid method reference
      final Function<String, String> f1 = MethodRefTest::passMeAround;
                                          ^
  non-static method passMeAround(String) cannot be referenced from a static context
1 error

I don't understand why the context is static. I read this but it does not seem to answer the problem at hand.

EDIT

Also according to oracle, "Reference to an instance method of an arbitrary object of a particular type" are possible via ContainingType::methodName

EDIT 2

@marko-topolnik helped me understand my mistake here. Function<String, String> f1 = MethodRefTest::passMeAround; refers to a static method String MethodRefTest.passMeAround(String)

BiFunction<MethodRefTest, String, String> f1 = MethodRefTest::passMeAround;

on the other hand, refers to the instance method of any instance, that is passed in the apply clause.

BiFunction<MethodRefTest, String, String> f2 = MethodRefTest::passMeAround;
//call instance method
f2.apply(new MethodRefTest(), "some string");
like image 690
Benjamin Avatar asked Aug 27 '15 16:08

Benjamin


People also ask

What is reference to an instance method of an arbitrary object of a particular type?

So the syntax for a reference to an instance method of an arbitrary object of a particular type is "ContainingType::methodName".

What is used to reference to an object on which method is invoked?

Summary. this Keyword in Java is a reference variable that refers to the current object. this in Java is a reference to the current object, whose method is being called upon. You can use “this” keyword to avoid naming conflicts in the method/constructor of your instance/object.

What is the difference between a method reference and a lambda expression?

Lambda expression is an anonymous method (method without a name) that has used to provide the inline implementation of a method defined by the functional interface while a method reference is similar to a lambda expression that refers a method without executing it.


1 Answers

Because you referred to it as

MethodRefTest::passMeAround

You should have referred to it as

this::passMeAround

providing the instance to use for context.

A different way to view your current code is to say that MethodRefTest::passMeAround is a BiFunction<MethodRefTest, String, String> and this lambda shape does not match the target site. So, alternatively, you may have written

public BiFunction<MethodRefTest, String, String> testReferences() {
  return MethodRefTest::passMeAround;
}

and in the main method

final MethodRefTest t = new MethodRefTest();
t.testReferences().apply( t, "foo" );

The material you have been reading may not be instructive enough, so let me expand. With

this::passMeAround

you get a lambda object which has captured the this instance from the context where it was created, but with

MethodRefTest::passMeAround

you get a "pure", non-capturing lambda which represents the invocation of the specified method on some instance, with some string argument, so when you apply it, you need to pass in both.

like image 168
Marko Topolnik Avatar answered Nov 08 '22 11:11

Marko Topolnik