- Method reference java 8
- Where we can use java method reference
- Syntax of java 8 method reference
- Different ways of method references in java
- Static method reference in java
- Example of java static method reference
- Object method reference in java
- Example of object method reference in java
- Object method reference By class type in java
- Reference to constructor in java
- Fast track reading :
- Method References
- Kinds 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
Method reference java 8
In java we refer classes using variables. We call methods using the reference variable of class. Wouldn’t it be great if we can refer the methods also? Thanks to java 8 feature releases, we can do it. Method reference in java 8 allows us to refer methods with class and method name directly.
Before going further, you should know about lambda expressions. Using lambda we can create anonymous functions for class without creating object or implementing. This helps to pass small functions as arguments.
Method reference is shorter way of writing lambdas expressions. Sometimes we just have another method call in a method body in such case method reference is used.
Where we can use java method reference
public void printString(String str)
These are the cases when we can use java 8 method reference so that code will be clean and easy to read.
Syntax of java 8 method reference
Most noteworthy point to notice is that in method reference syntax we use » :: » operator not the » . » operator. We don’t need to pass arguments. Arguments are provided by the context variables.
The most important point to note is we can only use method reference for lambda expression having single line of another method call.
Different ways of method references in java
Reference Type | Lambda Expression | Method Reference |
---|---|---|
Static Method Reference | (args) -> Class.staticMethod(args) eg: (String s) -> Long.parseLong(s) | Class::staticMethod eg: Long::parseLong |
Object Method Reference | (args) -> obj.instanceMethod(args) eg: (s) -> System.out.println(s) | obj::instanceMethod eg: System.out::println |
Instance Method Reference By Class Type | (obj, args) -> obj.instanceMethod(args) eg: (str) -> str.length() | Class::instanceMethod eg: String::length |
Constructor Reference | (args) -> new Class(args) eg: (size)->new ArrayList(size) | Class::new eg: ArrayList::new |
Static method reference in java
As we know in java we can call static methods using class name without creating object. Similarly, we can refer static methods using class name.
Example of java static method reference
In the example we have MethodReferenceTest class and static method print. Print method can have any logic. We are just printing message on console.
In main method we have created an Optional variable. Then call print method for the variable using class name.
public class MethodReferenceTest
public static void print(String msg)
public static void main(String[] args)
Optional msg = Optional.of(«StackTraceGuru»);
msg.ifPresent(text->MethodReferenceTest.print(text));
//Using Method reference to print method from MethodReferenceTest class
msg.ifPresent(MethodReferenceTest::print);
Output :
Printing: StackTraceGuru
Printing: StackTraceGuru
In the example we have called print method using lambda expression and equivalent Static method reference format.
Object method reference in java
In java if we need objects to call methods. However if in lambda expression we just have method call using object, We can refer such methods using class objects.
classObject :: methodName
Example of object method reference in java
We will use same example as static method reference, with the small change. First of all we have removed static from print method so it is a normal method now.
public class MethodReferenceTest
public static void print(String msg)
public static void main(String[] args)
Optional msg = Optional.of(«StackTraceGuru»);
MethodReferenceTest obj =new MethodReferenceTest();
//Using Method reference to print method from MethodReferenceTest class
Output :
Printing: StackTraceGuru
Printing: StackTraceGuru
In the example we have called print method using lambda expression and equivalent Object method reference format.
Object method reference By class type in java
Method reference can be used, if we have method calling from object while object is provided by context.
In the other words we can say the lambda expression scenario where we are just calling method and object is a input as from argument. Then we can use Method reference using class type. In this case the class type of object is used to called method.
Example of method reference by class type in java
In the example we have person class. Person class is having method printDetails. In another class we have main method. We have created an Optional variable of person type. We have to call printDetails method for the object.
System.out.println(«Person name is : «+name);
>
public class MethodReferenceTest
public static void main(String[] args)
Optional person = Optional.of(new Person(«Mac»));
//Using Method reference to print method from MethodReferenceTest class
Output :
Person name is : Mac
Person name is : Mac
In the example we have called printDetails method on the person object. The method is not static. It is not invoked using the class name.
Reference to constructor in java
If we are just creating new object in lambda expression, we can use constructor reference.
Example of constructor method reference in java
Similarly as previous example we have person class. Person class need a parameter to create new object. In main method we have Optional variable of String. We have to create person object from the name.
System.out.println(«Person name is : «+name);
public class MethodReferenceTest
public static void main(String[] args)
Optional msg = Optional.of(«Mac»);
msg.map (str-> new Person(o)).ifPresent(obj -> obj.printDetials());
//Using Method reference to print method from MethodReferenceTest class
Output :
Person name is : Mac
Person name is : Mac
In the example we have created person object using parameterized constructor. After that we have called printDetails method from the created object.
Fast track reading :
- Method reference in java allows us to refer methods with class and method name directly.
- Used to replace lambdas expressions having only another method call
- Syntax CLass :: mehtodName OR Object ::methodName
Method References
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
Consider again the Person class discussed in the section Lambda Expressions:
public class Person < // . LocalDate birthday; public int getAge() < // . >public LocalDate getBirthday() < return birthday; >public static int compareByAge(Person a, Person b) < return a.birthday.compareTo(b.birthday); >// . >
Suppose that the members of your social networking application are contained in an array, and you want to sort the array by age. You could use the following code (find the code excerpts described in this section in the example MethodReferencesTest ):
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]); class PersonAgeComparator implements Comparator < public int compare(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> Arrays.sort(rosterAsArray, new PersonAgeComparator());
The method signature of this invocation of sort is the following:
static void sort(T[] a, Comparator c)
Notice that the interface Comparator is a functional interface. Therefore, you could use a lambda expression instead of defining and then creating a new instance of a class that implements Comparator :
Arrays.sort(rosterAsArray, (Person a, Person b) -> < return a.getBirthday().compareTo(b.getBirthday()); >);
However, this method to compare the birth dates of two Person instances already exists as Person.compareByAge . You can invoke this method instead in the body of the lambda expression:
Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) );
Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:
Arrays.sort(rosterAsArray, Person::compareByAge);
The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b) . Each has the following characteristics:
- Its formal parameter list is copied from Comparator.compare , which is (Person, Person) .
- Its body calls the method Person.compareByAge .
Kinds of Method References
There are four kinds of method references:
Kind | Syntax | Examples |
---|---|---|
Reference to a static method | ContainingClass::staticMethodName | Person::compareByAge MethodReferencesExamples::appendStrings |
Reference to an instance method of a particular object | containingObject::instanceMethodName | myComparisonProvider::compareByName myApp::appendStrings2 |
Reference to an instance method of an arbitrary object of a particular type | ContainingType::methodName | String::compareToIgnoreCase String::concat |
Reference to a constructor | ClassName::new | HashSet::new |
The following example, MethodReferencesExamples , contains examples of the first three types of method references:
import java.util.function.BiFunction; public class MethodReferencesExamples < public static T mergeThings(T a, T b, BiFunction merger) < return merger.apply(a, b); >public static String appendStrings(String a, String b) < return a + b; >public String appendStrings2(String a, String b) < return a + b; >public static void main(String[] args) < MethodReferencesExamples myApp = new MethodReferencesExamples(); // Calling the method mergeThings with a lambda expression System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", (a, b) ->a + b)); // Reference to a static method System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", MethodReferencesExamples::appendStrings)); // Reference to an instance method of a particular object System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", myApp::appendStrings2)); // Reference to an instance method of an arbitrary object of a // particular type System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", String::concat)); > >
All the System.out.println() statements print the same thing: Hello World!
BiFunction is one of many functional interfaces in the java.util.function package. The BiFunction functional interface can represent a lambda expression or method reference that accepts two arguments and produces a result.
Reference to a Static Method
The method references Person::compareByAge and MethodReferencesExamples::appendStrings are references to a static method.
Reference to an Instance Method of a Particular Object
The following is an example of a reference to an instance method of a particular object:
class ComparisonProvider < public int compareByName(Person a, Person b) < return a.getName().compareTo(b.getName()); >public int compareByAge(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> ComparisonProvider myComparisonProvider = new ComparisonProvider(); Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
The method reference myComparisonProvider::compareByName invokes the method compareByName that is part of the object myComparisonProvider . The JRE infers the method type arguments, which in this case are (Person, Person) .
Similarly, the method reference myApp::appendStrings2 invokes the method appendStrings2 that is part of the object myApp . The JRE infers the method type arguments, which in this case are (String, String) .
Reference to an Instance Method of an Arbitrary Object of a Particular Type
The following is an example of a reference to an instance method of an arbitrary object of a particular type:
String[] stringArray = < "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" >; Arrays.sort(stringArray, String::compareToIgnoreCase);
The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b) , where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b) .
Similarly, the method reference String::concat would invoke the method a.concat(b) .
Reference to a Constructor
You can reference a constructor in the same way as a static method by using the name new . The following method copies elements from one collection to another:
public static , DEST extends Collection> DEST transferElements( SOURCE sourceCollection, Supplier collectionFactory) < DEST result = collectionFactory.get(); for (T t : sourceCollection) < result.add(t); >return result; >
The functional interface Supplier contains one method get that takes no arguments and returns an object. Consequently, you can invoke the method transferElements with a lambda expression as follows:
Set rosterSetLambda = transferElements(roster, () -> < return new HashSet<>(); >);
You can use a constructor reference in place of the lambda expression as follows:
Set rosterSet = transferElements(roster, HashSet::new);
The Java compiler infers that you want to create a HashSet collection that contains elements of type Person . Alternatively, you can specify this as follows:
Set rosterSet = transferElements(roster, HashSet::new);
Previous page: Lambda Expressions
Next page: When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions