Functional Interface in Java 8
Fast recall
Quick revision
Core answer
Object methods do not add to the count. The optional @FunctionalInterface annotation asks the compiler to verify the rule. Lambdas and method references need a compatible functional-interface target type.Foundational Java 8 knowledge — functional interfaces are the contract for lambdas
Thinking @FunctionalInterface creates the constraint — the annotation only validates it
Name the four key built-in functional interfaces: Predicate, Function, Consumer, Supplier
Interview-ready guide
Interview answer
A functional interface has one abstract function method. That signature is the target a lambda fills in. The interface may also contain default and static methods, and declarations matching public Object methods do not create another function method. @FunctionalInterface is optional, but it is useful because the compiler rejects changes that would stop the interface being functional. Common examples are Predicate for a boolean test, Function for a transformation, Consumer for an action, and Supplier for producing a value. Standard interfaces such as Runnable and Callable are functional interfaces too and are annotated in current Java APIs.
Functional Interface in Java 8
Direct Answer
A functional interface has one abstract function method, often called its SAM. It may also have default and static methods, and public methods matching Object methods do not add to the count. The optional @FunctionalInterface annotation asks the compiler to verify the rule. Lambdas and method references need a compatible functional-interface target type.
Code Example
import java.util.List;
public class OrderService {
@FunctionalInterface
interface OrderValidator {
boolean isValid(Order order);
default OrderValidator and(OrderValidator other) {
return order -> isValid(order) && other.isValid(order);
}
}
record Order(long id, double amount, String status) {}
List<Order> filterOrders(List<Order> orders, OrderValidator validator) {
return orders.stream().filter(validator::isValid).toList();
}
public static void main(String[] args) {
var service = new OrderService();
var orders = List.of(new Order(1L, 100.0, "PENDING"));
var valid = service.filterOrders(orders, order -> order.amount() > 50);
System.out.println(valid);
}
}
Common Mistakes & Pitfalls
- Adding a second abstract method: Freshers often add another abstract method to an interface marked @FunctionalInterface, breaking the SAM rule. The compiler catches this if you use the annotation, but without it you'll get cryptic lambda compilation errors.
- Confusing default methods with abstract methods: Default methods have implementations (the default keyword) so they don't count toward the one-abstract-method limit. Freshers sometimes think any method in the interface breaks the functional interface rule.
- Forgetting the annotation: While @FunctionalInterface is optional, skipping it means you won't get a compile-time error if someone later adds a second abstract method, breaking all the lambdas that use your interface.
Check your understanding
Answer these without looking back at the article.
- What is the difference between Predicate and Function?
- Can a functional interface have default methods?
- What is @FunctionalInterface and is it required?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.