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.