Published: April 10, 2016
Introduction
Java 8 introduces a powerful feature known as Method References, which provides a shorthand way of writing lambda expressions. Instead of writing full lambda expressions, you can use method references to refer to methods directly by their names. This makes your code more concise and easier to read.
In this tutorial, we will cover:
- What method references are and how they work.
- Different types of method references.
- How to use method references in various scenarios.
What Are Method References?
Method references allow you to refer to a method of an object or class without executing it. They provide a more compact and readable syntax for calling methods via lambda expressions.
Consider this example:
List<String> names = Arrays.asList("John", "Alice", "Bob");
names.forEach(name -> System.out.println(name)); // Using lambda
The above code uses a lambda expression, but with method references, it can be simplified:
names.forEach(System.out::println); // Using method reference
Both of these lines of code do exactly the same thing—print each name in the list—but the second version using method references is cleaner and more concise.
Types of Method References
There are four types of method references in Java:
- Reference to a static method:
This is used when the method being referenced is a static method of a class.class MathOperations { public static int multiply(int a, int b) { return a * b; } } public class MethodReferenceExample { public static void main(String[] args) { BinaryOperator<Integer> multiply = MathOperations::multiply; System.out.println(multiply.apply(5, 3)); // Output: 15 } }
Here,MathOperations::multiply
refers to the static methodmultiply()
in theMathOperations
class. - Reference to an instance method of an arbitrary object:
This is used when referencing a non-static method of an object, typically within a collection.class Printer { public void print(String message) { System.out.println(message); } } public class MethodReferenceExample { public static void main(String[] args) { Printer printer = new Printer(); Consumer<String> printMessage = printer::print; printMessage.accept("Hello, World!"); // Output: Hello, World! } }
Here,printer::print
refers to the instance methodprint()
of theprinter
object. - Reference to an instance method of a particular object:
This refers to calling an instance method of a specific object.class Greet { public void greet(String name) { System.out.println("Hello, " + name); } } public class MethodReferenceExample { public static void main(String[] args) { Greet greet = new Greet(); Consumer<String> greetPerson = greet::greet; greetPerson.accept("Alice"); // Output: Hello, Alice } }
greet::greet
references thegreet()
method of theGreet
object. - Reference to a constructor:
You can also refer to a constructor using method references.class Car { private String model; public Car(String model) { this.model = model; } public void display() { System.out.println("Car model: " + model); } } public class MethodReferenceExample { public static void main(String[] args) { Supplier<Car> carSupplier = () -> new Car("Tesla"); Car car = carSupplier.get(); car.display(); // Output: Car model: Tesla } }
The above example can be simplified using a constructor reference:Supplier<Car> carSupplier = Car::new; Car car = carSupplier.get(); car.display(); // Output: Car model: Tesla
Here,Car::new
is a reference to the constructor of theCar
class.
Advantages of Using Method References
- Conciseness: Method references reduce the verbosity of lambda expressions, making your code cleaner and easier to read.
- Readability: They clearly express the intent of the code, making it obvious that a method is being used directly, without the need for creating unnecessary lambdas.
- Reusability: Method references can be reused wherever the method is applicable, increasing code reusability.
When to Use Method References
- When the lambda expression is calling an existing method: If you have a lambda expression that simply calls an existing method, method references make your code much more readable.
list.forEach(item -> System.out.println(item)); // Lambda expression list.forEach(System.out::println); // Method reference
- In stream operations: You can use method references in stream operations, such as
map()
,filter()
,forEach()
, etc.List<String> names = Arrays.asList("John", "Alice", "Bob"); // Using method reference with map names.stream().map(String::toUpperCase).forEach(System.out::println);
Summary
Method references in Java 8 provide a shorthand way of referring to methods without executing them. They are especially useful for simplifying lambda expressions and improving code readability. There are four types of method references:
- Static method references
- Instance method references
- Particular object method references
- Constructor references
In this tutorial, we’ve covered the different types of method references and how they work. In the next tutorial, we will dive into The New Date-Time API in Java 8, and explore the powerful classes such as LocalDate
, LocalTime
, and LocalDateTime
.