1. Method References and Lambda Expressions as Implementations of Functional Interfaces
In Java, a functional interface (like Greet) has exactly one abstract method, which means it can be implemented by a lambda expression or a method reference that matches the interface’s method signature.
Lets take a looks at the below example we have an interface called Greet, Class MessageBoard and a MessageBoardFactory interface
@FunctionalInterfaceinterface Greet{ void greetings();}class MessageBoard{ public static void printMe(){ System.out.println("Hi"); } void printDetail(){ System.out.println("end"); }}interface MessageBoardFactory{ MessageBoard create();}public class MethodReferenceDemo { public static void main(String[] args) { Greet greet = MessageBoard::printMe; // static greet.greetings(); MessageBoard messageBoard = new MessageBoard(); Greet greet1 =messageBoard::printDetail; //instance greet1.greetings(); Consumer<MessageBoard> messageBoardConsumer= MessageBoard::printDetail; messageBoardConsumer.accept(new MessageBoard()); MessageBoardFactory messageBoardFactory = MessageBoard::new; MessageBoard messageBoard1 = messageBoardFactory.create(); messageBoard1.printDetail(); }}
When we write:
Greet greet = MessageBoard::printMe;
or
Greet greet1 = messageBoard::printDetail;
we’re essentially providing implementations of the greetings() method in Greet by referencing existing methods (printMe and printDetail) in MessageBoard. This works because:
- Java sees that
MessageBoard::printMeandmessageBoard::printDetailsatisfy the requirement forgreetings()and treats these methods as if they’re implementations ofgreetings(). - The signature of
Greet‘sgreetings()method matches the methods we reference inMessageBoard.
2. Matching Method Signatures
For a method reference to be used with a functional interface, the method referenced must have a compatible signature with the abstract method in that functional interface.
Here:
Greethas thevoid greetings()method, which takes no parameters and returnsvoid.- Both
printMe()(static method) andprintDetail()(instance method) inMessageBoardalso have the same signature:voidreturn type and no parameters.
Because the signatures match, Java can “assign” MessageBoard::printMe and messageBoard::printDetail to Greet greetings().
3. No Inheritance Relationship Required
Unlike traditional object-oriented programming (OOP) where method access usually requires an inheritance relationship (e.g., MessageBoard would have to implement Greet), functional interfaces and lambda expressions/method references break that requirement. The key is that only the method signature compatibility is necessary; no inheritance or direct relationship is required.
This feature allows Java to use functional interfaces more flexibly:
- Any class with a compatible method can be used with a functional interface, regardless of inheritance.
- This approach is common in functional programming paradigms, where the goal is to focus on functionality (method matching) rather than object hierarchies.
4. Java’s Internal Handling of Method References
When you use a method reference like MessageBoard::printMe, Java internally treats it as if you’re implementing the greetings() method in Greet by delegating it to printMe(). Similarly, messageBoard::printDetail is treated as if greetings() calls printDetail() on an instance of MessageBoard. Java essentially “adapts” the MessageBoard method to fit the Greet interface.
Summary
- Method references in Java work with functional interfaces by matching method signatures, not by requiring an inheritance relationship.
- This allows you to treat existing methods as implementations of functional interface methods without modifying the original class (i.e.,
MessageBoarddoes not need to implementGreet). - This flexibility is a hallmark of functional programming in Java, allowing you to compose functions and interfaces without rigid class relationships.

Leave a Reply