Since Java 8, in simplest words, the method references are a way to refer to methods or constructors without invoking them. They are a shorthand notation of a lambda expression and can be used anywhere a functional interface is expected.
The method references are denoted using ‘Class::methodName‘ type syntax. Let’s learn about different types of available method references in Java 8.
1. Types of Method References
Java 8 allows four types of method references.
| Method Reference To | Description | Syntax |
|---|---|---|
| Static method | Used to refer to static methods from a class | ClassName::staticMethodName |
| Instance method from a specific instance | Refer to an instance method using a reference to the supplied object | instance::instanceMethodName |
| Instance method from the Class type | Invoke the instance method on a reference to an object supplied by the context | ClassName::instanceMethodName |
| Constructor | Reference to a constructor | ClassName::new |
Please note that the method references always utilize the :: operator. Let’s explore each type with examples.
2. Method Reference to a Static Method
This method reference is used when we want to refer to a static method without invoking it. An example to use Math.max() which is a static method.
List<Integer> integers = Arrays.asList(1,12,433,5);
Optional<Integer> max = integers.stream().reduce( Math::max );
max.ifPresent(value -> System.out.println(value));
Output:
433
3. Method Reference to Instance Method of a Particular Object
This type of method reference refers to an instance method of a specific object. It is used when we want to call a method on a particular instance.
Consider the following PrintService class.
public class PrintService {
public void print(String message) {
System.out.println(message);
}
}
We can invoke the print() from an instance of PrintService using the ‘printService::print‘ method reference.
PrintService printService = new PrintService();
List<String> messages = Arrays.asList("Hello", "World", "Method", "References");
// using lambda expression
messages.forEach(message -> printService.print(message));
// iusing method reference
messages.forEach(printService::print);
The method reference is much cleaner and more readable, as the code clearly shows our intention.
4. Method Reference to Instance Method from a Class Type
In this method reference, we do not create any class instance. We can directly use the print() method from the class type PrintService.
List<String> messages = Arrays.asList("Hello", "World", "Method", "References");
messages.forEach(PrintService::print);
5. Method Reference to Constructor
This type of method reference refers to a constructor. It’s used when we want to create a new instance of a class.
For example, to create a new instance of ArrayList, we have use ArrayList::new.
ArrayList<Integer> integers = IntStream
.range(1, 100)
.boxed()
.collect(Collectors.toCollection( ArrayList::new ));
That’s 4 type of method references in java 8 lambda enhancements.
Happy Learning !!
ArrayList::new equivalent to new ArrayList() this is not correct this applicable only if “The target type of this expression must be a functional interface”
I meant not always correct there is a condition.
Consumer con = System.out::println;
con.accept(“Hello”);
How do you come to know about the parameters that are taken by these static methods.
For Example:
If I want to write System.out.println(“Hello”);
How do i write it using method reference ?
Consumer con = System.out::println;
con.accept(“Hello”);
System.out::println
This use case is usually used when working with java streams or for-each. In this case, we can normally write System.out::println after that we don’t need to create a separate instance of Consumer object or call its method. This can normally be used to iterate contents of Stream or any java objects of type java.lang.Iterable interface like List, Set and other collections.
This use case is usually used when working with java streams or for-each. In this case, we can normally write System.out::println after that we don’t need to create a separate instance of Consumer object or call its method. This can normally be used to iterate contents of Stream or any java objects of type java.lang.Iterable interface like List, Set and other collections.