Updated April 15, 2023
Introduction to Java Method References
The following article provides an outline for Java Method References. In JDK 8, lambda expressions are introduced to create anonymous methods in one line to perform one operation. But while writing a lambda expression when an existing method is called, such operation is made possible using Method References. This makes the expressions more compact and readable where a call to existing method exist. Furthermore, in method reference scope, resolution operator(:: ) is used to separate method name from class name.
Types of Java Method References
Let us see the need for method References with an example:
Code:
public class Employee {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDatejoiningDate;
Sex gender;
String emailAddress;
public int getNumberOfYears() {
}
public Calendar getJoiningDate() {
return joiningDate;
}
public static int compareByJoiningDate(Employeea, Employeeb) {
return a.joiningDate.compareTo(b.joiningDate);
}}
And if we want to sort the employee’s list by the joiningDate means who joins first, then we can call the below-given method in one of the subclass.
Code:
Person[] rosterAsArray = roster.toArray(new Employee[roster.size()]);
class JoiningDateComparator implements Comparator<Employee> {
public int compare(Employeea, Employeeb) {
return a.getJoiningDate().compareTo(b.getJoiningDate());
}
}
So, we can write a lambda expression to call the above method while sorting the list to compare the joining dates of 2 Employees.
Code:
Arrays.sort(rosterAsArray,
(a, b) ->Person.compareByAge(a, b)
);
Or we can call the method in the below manner; both have the same meaning to call the method for each pair of objects in the array.
Code:
Arrays.sort(rosterAsArray, Person::compareByAge)
Following four types of Method References exist in JDk 8:
1. Reference to static method
Reference to a static method using :: operator is known as Reference to a static Method.
Syntax:
ClassName::MethodName()
Working:
- Here the method being referenced is of a static type that means no instance of the class is required to call this method; instead, only Classname would be sufficient.
- Thus when one metionsClassName::MethodName in his lambda expression, JRE goes to that class to find a static method in the class mentioned. Since it is a call to static method thus cannot be mentioned under a non-static block.
Example:
In the below example, the static method add of Addition class is called using the functionality of bifunction class in java.util package, where the reference of this method is stored in the myObj object and is passed with values that are needed to be passed as arguments.
Code:
import java.util.function.BiFunction;
class Addition{
public static int add(int a, int b){
return a+b;
}
}
public class HelloWorld {
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer>myObj = Addition::add;
int res = myObj.apply(30, 5);
System.out.println("Sum of given number is: "+res);
}
}
Output:
2. Reference to an instance method of a particular object
Syntax:
object::methodName()
Working:
- In this type of reference, one uses an object of the class to refer to one of its instance methods. Here JRE checks if the arguments passed are of same type as mentioned in the method declaration.
- This helps to write a lambda expression using the instance methods of the class.
Example:
In the below example, the showName method of class HelloWorld is called using method reference to instance methods.
Code:
interface MyInterface{
void display();
}
public class HelloWorld {
public void showName(){
System.out.println("Call to method ShowName");
}
public static void main(String[] args) {
HelloWorld obj = new HelloWorld();
MyInterface ref = obj::showName;
ref.display();
}
}
Output:
3. Reference to an instance method of an arbitrary object of a particular type
Syntax:
ClassName :: instanceMethodName()
Working:
- This is the same type of reference as given above, difference lies here that the object being referred to here are continuously changing, which means many objects are calling the same method but of the same type using method referencing.
Example: In the below example, we are calling the compareToIgnoreCase method for all the strings stored in the array. Thus instead of passing different objects one by one, this occurs in a single statement using a roster.
Code:
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
String[] empArray = { "John", "Jack", "Aditya", "Vishal", "Saurabh", "Amanda", "Daniel"};
Arrays.sort(empArray, String::compareToIgnoreCase);
System.out.println("Sorted list of names of Employees \n");
for(String str: empArray){
System.out.println(str);
}
}
}
Output:
4. Reference to a constructor
Syntax:
myFunc(roster, HashSet<MyClass>::new);
Working:
- This reference call also is made to call a constructor of a class.
- For this, the ‘new’ keyword is being used in a lambda expression, and such that JRE infers to call the constructor of that particular class.
Let’s take an example of a lambda expression that contains a call to the below method and needs a new constructor of HashSet to be passed.
Code:
publicstatic<T, MYSRCextends Collection<T>, MYDESTextends Collection<T>>
MYDEST MyMethod(
MYSRC src,
Supplier< MYDEST>dest) {
MYDEST res = collectionFactory.get();
for (T t : src)
{res.add(t);
}
returnres;
}
Then the lambda expression would be like:
Code:
Set<myClass>rosterSet = MyMethod(roster, HashSet::new);
Here JRE automatically infers that the passed arguments contain objects of myClass type or either we can use the below lambda expression to
Set<myClass>rosterSet = transferElements(roster, HashSet<myClass>::new);
Example: In the below example, a constructor of a firstReference class is being called using ‘new’ operator and stored in a reference variable ‘inObj’. This reference variable is then used to refer to the instance methods of this class.
Code:
@FunctionalInterface
interface firstInterface{
firstReference show(String say);
}
class firstReference{
public firstReference(String say){
System.out.print(say);
}
}
public class HelloWorld {
public static void main(String[] args) {
//Method reference to a constructor
firstInterface inObj = firstReference::new;
inObj.show("Let’s begin learning Contructor type method reference");
}
}
Output:
Conclusion
Method Reference is a way to make a call to an existing method in lambda expressions being used in the application. This feature has been introduced with JDK 1.8 to make lambda expressions more compact and reuse the existing code. There are four ways to make calls to the methods of the class names as shown above.
Recommended Articles
This is a guide to Java Method References. Here we discuss the introduction to Java Method References along with types, respectively. You may also have a look at the following articles to learn more –