# Java 8 Method Reference Example

**Date:** 2018-01-19

Java 8 Method References: A Comprehensive Guide

Java 8 introduced a powerful feature called method references, a concise way to represent lambda expressions that simply invoke existing methods.  Before diving into the specifics, it's helpful to understand the context. Lambda expressions themselves were a significant addition to Java, providing a more compact and readable way to pass behavior to methods, essentially creating anonymous methods.  Method references take this concept a step further, streamlining lambda expressions even more when they're just calling a pre-existing method.  Instead of writing a full lambda expression, a method reference directly points to the method to be executed.

The core idea behind method references is to reduce redundancy. If a lambda expression's sole purpose is to call a specific method, writing a separate lambda expression is unnecessary.  A method reference acts as a shorthand, improving both code readability and maintainability.  This is achieved using a double colon operator (::), which explicitly links the method's name to its context (either a class or an object instance).

Crucially, both method references and lambda expressions must be compatible with a functional interface.  A functional interface, in Java, is an interface that contains only one abstract method. This ensures type safety and allows the Java compiler to understand how the method reference should be used.  The method reference replaces the body of the functional interface's abstract method.  Therefore, the signature of the method reference must perfectly match the signature of the functional interface's method.  A key limitation is that method references cannot accept additional arguments; they are strictly limited to invoking the referenced method with the arguments provided by the functional interface.  This restriction avoids scenarios requiring features like currying, which Java doesn't directly support without helper functions or lambda expressions.

There are four main types of method references:

1.  **References to static methods:** These references directly point to static methods within a class.  Imagine a scenario where a functional interface requires a method that checks if a number is even. Instead of writing a lambda expression containing the logic, you can use a method reference to a pre-existing static `isEven()` method. The method reference, in this instance, would be `ClassName::isEven`. This concisely expresses the intention without repeating the even-number-checking logic.

2.  **References to instance methods of a particular object:** This type of reference targets a specific instance method on a known object. Let's say you have a `PrintStream` object (like `System.out`) and want to use its `println()` method within a lambda expression.  The method reference would be `System.out::println`. This directly points to the `println()` method associated with the `System.out` object.

3.  **References to instance methods of an arbitrary object of a particular type:** This is slightly more abstract.  It points to an instance method, but instead of a specific object, it refers to the method as it would be called on any object of a given class.  Suppose a `Person` class has a `getName()` method. The method reference `Person::getName` indicates that, when used within a lambda expression context, this method will be invoked on a `Person` object. The actual `Person` object will be provided by the surrounding context (the lambda expression's parameters).

4.  **References to constructors:**  This type of method reference points to a constructor of a class.  It's indicated by `ClassName::new`.  This is analogous to the other types, allowing the creation of new objects concisely within functional interface contexts.  This is particularly useful when creating objects based on supplied parameters within a functional framework.

To illustrate with a simplified example, let's consider a functional interface named `NumberChecker` with a method `check(int number)`.  A lambda expression to check if a number is even might look like `(number) -> (number % 2 == 0)`. However, using a method reference to a static `isEven(int number)` method, the equivalent code would be simply `ClassName::isEven`. This clearly demonstrates the reduction in code complexity and enhanced readability.


The practical application of method references goes beyond simple examples.  They significantly improve code clarity in complex scenarios involving functional programming paradigms.  Frameworks heavily relying on functional interfaces (like streams in Java) benefit greatly from method references by allowing developers to express their intent directly, rather than embedding the method's implementation within a lambda expression.

Creating a Java project with Maven and Eclipse, as described in the original document, involves standard steps for setting up a Maven project. The process involves using Eclipse's built-in Maven support to create a new project, specifying the project coordinates (group ID, artifact ID), and potentially adding necessary dependencies via the `pom.xml` file.  The creation of these files (like `MethodReferenceEx1.java`, `MethodReferenceEx2.java`, and so forth) showcases the implementation of each of the four types of method references. The subsequent compilation and execution of this code demonstrate the practical usage of these concepts in a running Java program. Each of these Java files would contain the specific code showcasing a different type of method reference, illustrating how each approach relates to its corresponding functional interface and desired operation.

In essence, Java 8's method references provide a compelling combination of concision and readability, promoting cleaner and more maintainable code when working with functional interfaces and lambda expressions.  The elegant syntax and direct referencing of existing methods significantly reduce boilerplate and enhance the overall expressiveness of the Java language in a functional programming context. By avoiding the redundant repetition of lambda expression bodies, they create a more fluent and efficient coding style.  While the underlying concept leverages functional programming principles, the result is a more intuitive and easier-to-understand way to achieve common programming tasks.


**[Read more](https://examples.javacodegeeks.com/core-java/java-8-method-reference-example/)**
