Functional Interface and Marker Interface in Java
Functional interfaces and marker interfaces are important concepts in Java, especially when working with Java 8 features, lambda expressions, functional programming, serialization, and enterprise application design. A functional interface represents behavior through exactly one abstract method, while a marker interface represents a property, capability, or category of a class.
What Is a Functional Interface in Java?
A functional interface is an interface that contains exactly one abstract method. It can contain multiple default and static methods. Functional interfaces provide the target type for lambda expressions and method references introduced in Java 8.
@FunctionalInterface
interface PaymentProcessor {
void processPayment(double amount);
}The PaymentProcessor interface has only one abstract method, processPayment(), so it can be used with a lambda expression.
PaymentProcessor processor =
amount -> System.out.println("Processing payment: " + amount);
processor.processPayment(5000);Why Are Functional Interfaces Needed?
- They provide a target type for lambda expressions
- They allow behavior to be passed as a value
- They reduce boilerplate code compared with anonymous classes
- They are heavily used by the Java Stream API
- They support functional programming in Java
- They are useful for callbacks, event handlers, and strategy implementations
Functional Interface Before Java 8
Before Java 8, implementing an interface with a single method commonly required an anonymous class. Lambda expressions made this code much shorter and easier to read.
PaymentProcessor processor = new PaymentProcessor() {
@Override
public void processPayment(double amount) {
System.out.println("Processing: " + amount);
}
};Functional Interface Using Lambda Expression
PaymentProcessor processor =
amount -> System.out.println("Processing: " + amount);The lambda expression provides the implementation of the single abstract method. This is one of the main reasons functional interfaces are important in modern Java development.
What Is @FunctionalInterface?
@FunctionalInterface is a compiler-checked annotation that indicates an interface is intended to contain exactly one abstract method. The annotation is optional, but it protects the interface from accidentally becoming non-functional when another developer adds an abstract method.
@FunctionalInterface
interface DiscountCalculator {
double calculateDiscount(double amount);
}Can a Functional Interface Have Default and Static Methods?
Yes. A functional interface can contain multiple default and static methods as long as it has exactly one abstract method.
@FunctionalInterface
interface PaymentProcessor {
void processPayment(double amount);
default void validate(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Invalid amount");
}
}
static boolean isValidCurrency(String currency) {
return currency.equals("INR") || currency.equals("USD");
}
}Real-World Functional Interface Example
A common real-world use case is a discount strategy in an e-commerce application. Instead of creating separate classes for regular, premium, and VIP discounts, a functional interface can represent the discount calculation behavior.
@FunctionalInterface
interface DiscountCalculator {
double calculateDiscount(double amount);
}
DiscountCalculator regular =
amount -> amount * 0.05;
DiscountCalculator premium =
amount -> amount * 0.15;
DiscountCalculator vip =
amount -> amount * 0.25;
System.out.println(regular.calculateDiscount(10000));
System.out.println(premium.calculateDiscount(10000));
System.out.println(vip.calculateDiscount(10000));Functional Interface and Strategy Pattern
Functional interfaces can provide a simple implementation of the Strategy Pattern. Instead of tightly coupling a service to one implementation, behavior can be passed into the service.
@FunctionalInterface
interface PaymentStrategy {
boolean pay(double amount);
}
class CheckoutService {
public void checkout(double amount, PaymentStrategy strategy) {
boolean success = strategy.pay(amount);
if (success) {
System.out.println("Order placed successfully");
} else {
System.out.println("Payment failed");
}
}
}
PaymentStrategy upi = amount -> {
System.out.println("Processing UPI payment: " + amount);
return true;
};
CheckoutService checkout = new CheckoutService();
checkout.checkout(5000, upi);Built-In Functional Interfaces in Java
- Predicate<T> - accepts a value and returns boolean using test(T)
- Function<T,R> - accepts one value and transforms it into another value using apply(T)
- Consumer<T> - accepts a value and performs an operation using accept(T)
- Supplier<T> - supplies a value using get() without accepting an input
- UnaryOperator<T> - accepts and returns the same type
- BinaryOperator<T> - accepts two values of the same type and returns the same type
Functional Interfaces Used by Stream API
Functional interfaces are heavily used by Java Streams. The filter operation commonly uses Predicate, map uses Function, and forEach uses Consumer.
List<Integer> numbers =
List.of(10, 15, 20, 25, 30, 35);
numbers.stream()
.filter(n -> n > 20)
.filter(n -> n % 2 == 0)
.map(n -> n * 10)
.forEach(n -> System.out.println(n));What Is a Marker Interface in Java?
A marker interface is an interface that does not declare abstract methods. It is used to mark a class with a particular property, capability, or category. Marker interfaces are part of Java's type system.
interface Exportable {
}
class Employee implements Exportable {
String name;
double salary;
}The Employee class is marked as Exportable. Code can check whether an object implements Exportable and allow only those objects to be exported.
Why Are Marker Interfaces Needed?
- They provide type-level metadata
- They identify a capability or category of a class
- They allow checks using instanceof
- They can be used as method parameter types
- They allow the compiler and runtime to recognize a special type relationship
Real-World Marker Interface Example
Suppose an enterprise application allows only certain objects to be exported. An Exportable marker interface can identify objects that are permitted to participate in the export process.
interface Exportable {
}
class Employee implements Exportable {
String name;
double salary;
}
class Customer implements Exportable {
String name;
String email;
}
class SecurityToken {
}
class DataExporter {
public void export(Object object) {
if (object instanceof Exportable) {
System.out.println(
"Exporting: " +
object.getClass().getSimpleName()
);
} else {
throw new IllegalArgumentException(
"Object is not exportable"
);
}
}
}Classic Java Marker Interfaces
- Serializable - indicates that an object can participate in Java serialization
- Cloneable - indicates that an object supports cloning through Object.clone()
- Remote - identifies an object that can be used with Java Remote Method Invocation
Marker Interface vs Annotation
Marker interfaces and annotations can both provide metadata, but a marker interface is a real Java type and participates directly in the type system. An annotation is generally metadata that can be inspected by reflection or framework infrastructure.
interface Exportable {
}
class Employee implements Exportable {
}
void export(Exportable object) {
System.out.println("Exporting object");
}With a marker interface, the compiler can prevent an unrelated object from being passed to a method that accepts Exportable. This is one important difference between a marker interface and a simple annotation.
Functional Interface vs Marker Interface
- Functional interface has exactly one abstract method, while a marker interface has no abstract methods
- Functional interfaces represent behavior, while marker interfaces represent a property or capability
- Functional interfaces can be used with lambda expressions, while marker interfaces are not lambda targets
- Functional interfaces are commonly used with Streams, callbacks, and strategies
- Marker interfaces are commonly used for type identification and special capabilities
- Predicate, Function, Consumer, and Supplier are functional interfaces
- Serializable and Cloneable are classic marker interfaces
Easy Way to Remember the Difference
Think of a functional interface as BEHAVIOR and a marker interface as PROPERTY or CAPABILITY. A functional interface answers the question 'What should this object do?', while a marker interface answers 'What kind of capability does this object have?'
@FunctionalInterface
interface PaymentProcessor {
void processPayment();
}
interface Exportable {
}
// Functional Interface = BEHAVIOR
// Marker Interface = PROPERTY / CAPABILITYAdvanced Example: Functional Interface and Marker Interface Together
In an event-processing system, a marker interface can identify critical events while a functional interface defines how those events should be handled. The marker interface answers what type of event it is, while the functional interface defines what action should be performed.
interface CriticalEvent {
}
@FunctionalInterface
interface EventHandler<T> {
void handle(T event);
}
class PaymentFailedEvent implements CriticalEvent {
private final String transactionId;
PaymentFailedEvent(String transactionId) {
this.transactionId = transactionId;
}
public String getTransactionId() {
return transactionId;
}
}
EventHandler<PaymentFailedEvent> handler =
event -> System.out.println(
"Alerting operations team for transaction: "
+ event.getTransactionId()
);Interview Questions on Functional Interfaces
- What is a functional interface in Java?
- Why were functional interfaces introduced in Java 8?
- Is @FunctionalInterface mandatory?
- Can a functional interface have default methods?
- Can a functional interface have static methods?
- Can a functional interface extend another interface?
- How are functional interfaces related to lambda expressions?
- Which functional interfaces are provided by Java?
- How are Predicate, Function, Consumer, and Supplier different?
- How are functional interfaces used in the Stream API?
Interview Questions on Marker Interfaces
- What is a marker interface in Java?
- Why are marker interfaces used?
- What are examples of marker interfaces in Java?
- Why is Serializable called a marker interface?
- What is the difference between a marker interface and an annotation?
- Can marker interfaces be checked using instanceof?
- Can a marker interface be used as a method parameter type?
Functional Interface vs Marker Interface: Interview Summary
- Functional Interface → exactly one abstract method
- Marker Interface → no abstract methods
- Functional Interface → represents behavior
- Marker Interface → represents property or capability
- Functional Interface → supports lambda expressions
- Marker Interface → supports type-level identification
- Functional Interface examples → Predicate, Function, Consumer, Supplier
- Marker Interface examples → Serializable, Cloneable, Remote
Key Takeaway
The easiest way to remember these concepts is: Functional Interface means BEHAVIOR, while Marker Interface means PROPERTY or CAPABILITY. Functional interfaces enable lambda expressions and functional programming, whereas marker interfaces provide type-level information that can be used by Java, libraries, frameworks, or application code.