Method reference – Lambda expression, which calls known method, written in shorter, more compact way.
This is how we can define it in a short way. There are 4 types of method references:
- Reference to a static method
- Reference to an instance method of a particular object
- Reference to an instance method of an arbitrary object of a particular type
- Reference to a constructor
While it is almost the same thing as Lambda expressions, lets reuse and extend a bit the same example from my previous post about Lambda expressions. Here is a quick sample for each of reference types:
-
Reference to a static method
ContainingClass::staticMethodName
import java.util.function.Function; public class StaticReferenceSample { private static int doSquare(int a) { return a * a; } public static void main(String[] args) { Function<Integer, Integer> sf = StaticReferenceSample::doSquare; System.out.println("Square of 5: " + sf.apply(5)); } }
StaticReferenceSample::doSquare is a reference to a static method “int doSquare(int a)”. As we see, it is not necessary to provide an argument, it is passed implicitly
-
Reference to an instance method of a particular object
containingObject::instanceMethodName
public class InstnceReferenceSample { public static void main(String[] args) { List<String> candidates = new ArrayList<String>(); List<String> participants = new ArrayList<String>(); candidates.add("John"); candidates.add("Peter"); candidates.add("Matt"); candidates.forEach(participants::add); System.out.println("Participants:"); participants.forEach(System.out::println); } }
In this example there two types of references combined. participants::add stands for an instance method reference. And System.out::println stands for a static reference as “out” is an static member of System class.
-
Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
public class ArbitraryObjectRefSample { public static void main(String[] args) { List<Participant> participants = new ArrayList<Participant>(); participants.add(new Participant("John")); participants.add(new Participant("Peter")); participants.add(new Participant("Matt")); System.out.println("Participants:"); participants.forEach(Participant::print); } private static class Participant { private String name; public Participant(String name) { this.name = name; } public void print() { System.out.println(name); } } }
Here Participant::print is a reference to an instance of “participants” method “print” of type “Participant”. The essential difference between a static reference, instance method reference and instance method of an arbitrary type is that the latter invokes a method onto the current object and the first two – pass the current object into the method.
An alternative for non Lambda and Method reference syntax for relevant code snippet would be like this:
//... System.out.println("Participants:"); for (Participant part : participants){ part.print(); } //...
-
Reference to a constructor
ClassName::new
Reference to object constructor works the same way as to static method, just referencing it with a name “new”.
public class ArbitraryObjectRefSample { public static void main(String[] args) { List<String> candidates = new ArrayList<String>(); List<Participant> participants = new ArrayList<Participant>(); Function<String,Participant> participant=Participant::new; candidates.add("John"); candidates.add("Peter"); candidates.add("Matt"); candidates.forEach(s ->participants.add(participant.apply(s))); System.out.println("Participants:"); participants.forEach(Participant::print); } private static class Participant { private String name; public Participant(String name) { this.name = name; } public void print() { System.out.println(name); } } }
In this sample via interface Function<String,Participant> we create function to construct new object of Participant.
For more information about Java method references please refer to documentation.