Method References: Simplifying Your Code

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:

  1. 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 method multiply() in the MathOperations class.
  2. 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 method print() of the printer object.
  3. 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 the greet() method of the Greet object.
  4. 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 the Car 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:

  1. Static method references
  2. Instance method references
  3. Particular object method references
  4. 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 LocalDateLocalTime, and LocalDateTime.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *