Great question! The terms bound method reference and unbound method reference are not official Java terms, but they are very useful to understand how method references work internally — and they come up a lot in advanced interviews.
📚 What is a Bound Method Reference?
A bound method reference is a method reference that is tied to a specific existing object (instance) at the time of reference creation.
🔗 Example: Bound Method Reference
String greeting = "Hello";
Supplier<Integer> lengthSupplier = greeting::length;
// This is a bound method reference
✅ Explanation:
greetingis an existing object.- The method reference
greeting::lengthis bound to that specific object. - When you call
lengthSupplier.get(), it callsgreeting.length().
Bound = “I already know which object to call the method on.”
📚 What is an Unbound Method Reference?
An unbound method reference is a method reference that is tied to a class (type), but not tied to any specific object yet.
The actual object will be provided later (at runtime), typically by the stream pipeline or functional interface handling.
🔗 Example: Unbound Method Reference
Function<String, Integer> lengthFunction = String::length;
// This is an unbound method reference
✅ Explanation:
- The method reference points to
String.length(), but it doesn’t know which String to call it on yet. - Later, when this function is applied (like in a stream), the actual String object will be passed at runtime.
Stream.of("Apple", "Banana")
.map(String::length) // Unbound - each element provides the object
.forEach(System.out::println);
🧵 Side-by-Side Comparison
| Type | Bound Method Reference | Unbound Method Reference |
|---|---|---|
| Tied to Object? | ✅ Yes, known in advance | ❌ No, object provided later |
| Example | greeting::length | String::length |
| Method Type | Instance Method | Instance Method |
| Typical Functional Interface | Supplier (takes nothing, returns result) | Function<T, R> (takes object, returns result) |
| Example Use Case | Calling on a specific object | Processing elements in stream |
🔥 Example Showing Both Together
String greeting = "Hello";
// Bound: tied to 'greeting' directly
Supplier<Integer> bound = greeting::length;
System.out.println(bound.get()); // Calls greeting.length()
// Unbound: tied to 'String' class - actual object comes later
Function<String, Integer> unbound = String::length;
System.out.println(unbound.apply("World")); // Calls "World".length()
⚠️ Important Rule
- Both are instance method references.
- The difference is when and how the object is supplied:
- Bound: You already know the object (fixed).
- Unbound: The object comes later, provided externally.
📊 Quick Summary Table
| Type | Example | Explanation |
|---|---|---|
| Static Method Reference | Math::max | Class method, no object needed |
| Bound Method Reference | greeting::length | Instance method tied to specific object (greeting) |
| Unbound Method Reference | String::length | Instance method tied to class (String), object supplied later |
| Constructor Reference | ArrayList::new | Constructor call (object creation) |
🎯 Final Pro Tip for Interviews
✅ When asked about method references, always explain:
- There are 4 types of method references.
- Instance method references come in two flavors: bound (known object) and unbound (object supplied later).
- Static and constructor references are simpler (no instance needed for static; constructor creates new instance).