Method References
1. What Is a Method Reference?
A method reference is a shorter way to write a lambda when the lambda only calls an existing method.
Syntax:
ClassName::method
Example:
Consumer<String> printer = s -> System.out.println(s);
Can become:
Consumer<String> printer = System.out::println;
Both mean: take a String and print it.
2. When to Use It
Use a method reference when there is no extra logic.
// Lambda
list.forEach(s -> System.out.println(s));
// Method reference
list.forEachprintln;
If extra logic is needed, use a lambda:
list.forEach(s -> System.out.println(s.toUpperCase()));
3. Four Types of Method References
| Type | Syntax | Meaning |
|---|---|---|
| Static | Class::staticMethod |
Calls static method |
| Bound | object::method |
Object already fixed |
| Unbound | Class::method |
Object provided later |
| Constructor | Class::new |
Creates an object |
4. Static Method Reference
References a static method.
DoubleUnaryOperator sqrt = Math::sqrt;
Same as:
DoubleUnaryOperator sqrt = x -> Math.sqrt(x);
System.out.println(sqrt.applyAsDouble(25)); // 5.0
Pattern:
ClassName::staticMethod
Examples:
Math::sqrt
Math::max
Integer::parseInt
5. Bound Method Reference
The object is already fixed.
Consumer<String> printer = System.out::println;
Same as:
Consumer<String> printer =
s -> System.out.println(s);
Here:
System.out → fixed object
println → method
Pattern:
object::instanceMethod
Think: object is already known.
6. Unbound Method Reference
The object is provided later.
Function<String, Integer> length = String::length;
Same as:
Function<String, Integer> length =
s -> s.length();
Then:
System.out.println(length.apply("Hello")); // 5
The object "Hello" is provided when apply() is called.
Pattern:
ClassName::instanceMethod
Think: object will be provided later.
7. Bound vs Unbound
Bound
String name = "Hello";
Function<String, String> f = name::toUpperCase;
The object is fixed:
name → toUpperCase()
Same as:
() -> name.toUpperCase()
Unbound
Function<String, String> f = String::toUpperCase;
The object is provided later:
f.apply("hello");
Same as:
s -> s.toUpperCase()
Easy Rule
object::method → Bound
Class::method → Unbound
8. Constructor Reference
ClassName::new references a constructor.
Supplier<ArrayList<String>> supplier =
ArrayList::new;
Same as:
Supplier<ArrayList<String>> supplier =
() -> new ArrayList<>();
Then:
ArrayList<String> list = supplier.get();
Constructor with Parameters
Function<Integer, ArrayList<String>> creator =
ArrayList::new;
Same as:
size -> new ArrayList<>(size);
The functional interface determines which constructor is used.
Pattern:
ClassName::new
9. Common Example with forEach()
List<String> names =
List.of("Alice", "Bob", "Charlie");
names.forEachprintln;
Same as:
names.forEach(name -> System.out.println(name));
10. Method Reference with Your Own Class
class Person {
private String name;
Person(String name) {
this.name = name;
}
String getName() {
return name;
}
}
Method reference:
Function<Person, String> getName =
Person::getName;
Same as:
person -> person.getName();
Usage:
Person p = new Person("John");
System.out.println(getName.apply(p)); // John
Quick Comparison
| Lambda | Method Reference |
|---|---|
x -> Math.sqrt(x) |
Math::sqrt |
x -> System.out.println(x) |
System.out::println |
x -> x.length() |
String::length |
() -> new ArrayList<>() |
ArrayList::new |
Quick Revision
Class::staticMethod → Static
object::instanceMethod → Bound
Class::instanceMethod → Unbound
Class::new → Constructor
Simple Definition
Method reference = shorter lambda when the lambda only calls an existing method.