Java8 Method References
# Java 8 Method References
Method references in Java 8 provide a way to refer to a method without executing it. They are a syntactic shortcut for lambda expressions that only call an existing method. By using method references, you can make your code more compact, readable, and free of redundant boilerplate.
A method reference is identified by the double colon operator `::`.
---
## The Four Types of Method References
To understand the four types of method references, let's define a `Car` class and a custom functional interface `Supplier` (similar to the built-in `java.util.function.Supplier` introduced in Java 8).
```java
package com.youtip.main;
@FunctionalInterface
public interface Supplier {
T get();
}
class Car {
// Supplier is a functional interface used here in combination with lambdas/method references
public static Car create(final Supplier supplier) {
return supplier.get();
}
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
}
```
Using the `Car` class above, we can explore the four distinct types of method references:
### 1. Reference to a Constructor
* **Syntax:** `Class::new` or `Class::new` for generic classes.
* **Example:**
```java
// Refers to the default constructor Car()
final Car car = Car.create(Car::new);
final List cars = Arrays.asList(car);
```
### 2. Reference to a Static Method
* **Syntax:** `Class::static_method`
* **Example:**
```java
// Refers to the static method collide(Car car)
cars.forEach(Car::collide);
```
### 3. Reference to an Instance Method of an Arbitrary Object of a Particular Type
* **Syntax:** `Class::method`
* **Example:**
```java
// Refers to the instance method repair() of an arbitrary Car object
cars.forEach(Car::repair);
```
*Note: Although this uses the class name, it resolves to the instance method `repair()` invoked on each `Car` element in the stream/list.*
### 4. Reference to an Instance Method of a Particular Existing Object
* **Syntax:** `instance::method`
* **Example:**
```java
final Car police = Car.create(Car::new);
// Refers to the instance method follow(Car another) on the specific 'police' instance
cars.forEach(police::follow);
```
---
## Complete Code Example
Below is a complete, runnable example demonstrating how to use a method reference to print the elements of a list.
### `Java8Tester.java`
```java
import java.util.List;
import java.util.ArrayList;
public class Java8Tester {
public static void main(String args[]) {
List names = new ArrayList<>();
names.add("Google");
names.add("YouTip");
names.add("Taobao");
names.add("Baidu");
names.add("Sina");
// Using System.out::println as a reference to an instance method of a particular object (System.out)
names.forEach(System.out::println);
}
}
```
### Compilation and Execution
Compile and run the program using your terminal:
```bash
$ javac Java8Tester.java
$ java Java8Tester
Google
YouTip
Taobao
Baidu
Sina
```
---
## Key Considerations and Best Practices
* **Readability First:** Method references are designed to make your code cleaner. If a method reference makes the code harder to understand than a standard lambda expression, stick to the lambda expression.
* **Type Safety:** The compiler automatically checks if the functional interface's abstract method descriptor matches the signature of the referenced method. If they do not match, a compilation error occurs.
* **Null Safety:** When using the `instance::method` syntax, ensure that the target instance is not `null` at the time the method reference is evaluated, otherwise a `NullPointerException` will be thrown.
YouTip