Java.Core.Why lambda work only with functional interfaces ?

🌐 First, What is a Functional Interface?

A functional interface is an interface with exactly one abstract method.
Examples:
Runnable (1 method: run())
Comparator (1 method: compare())
Callable (1 method: call())
Predicate (1 method: test())

@FunctionalInterface
public interface Printer {
    void print(String message);  // One abstract method = functional interface
}

🔥 Why Lambda Works Only with Functional Interfaces

Key Reason: Type Inference — Functional Interface gives context.

  • A lambda itself has no type.
  • To assign a lambda to a variable (or pass it into a method), the compiler needs to know what “shape” it fits — meaning:
    • How many arguments?
    • What are their types?
    • What return type?
  • Functional interfaces provide exactly that “shape” — because they have only one abstract method.
  • That one abstract method defines the “functional shape” (called a functional descriptor) the lambda must match.

💡 Example

This works:

Consumer<String> printer = message -> System.out.println(message);

Why?

  • Consumer is a functional interface with:
void accept(T t)

The lambda message -> System.out.println(message) matches this perfectly:

  • One argument (String message)
  • Returns void

This does NOT work:

interface NotFunctional {
    void doSomething();
    void doSomethingElse();
}

// ❌ This won't compile
NotFunctional obj = () -> System.out.println("Hello");

Why?

  • NotFunctional has two abstract methods, so Java can’t infer the shape of the lambda.
  • Java has no way to know if the lambda is meant to be doSomething() or doSomethingElse().

📣 Rule: Lambda Needs a Functional Descriptor

Interface TypeCan Assign Lambda?Why?
1 abstract method (functional interface)✅ YesCompiler knows the “shape”
2+ abstract methods (regular interface)❌ NoNo way to know which method the lambda targets

💡 How Java Knows the Types Inside the Lambda

Example:

BiFunction<String, Integer, String> repeat = (text, count) -> text.repeat(count);
  • BiFunction is:
public interface BiFunction<T, U, R> {
    R apply(T t, U u);
}

So:

  • T = String
  • U = Integer
  • R = String

✅ The lambda gets correct argument and return types from the functional interface.


🧰 Summary — Why Functional Interface is Required

Why Functional Interface?Explanation
Defines lambda’s shapeNumber, type of parameters, and return type
Allows type inferenceCompiler can validate lambda at compile time
Ensures compatibilityLambdas work only in contexts expecting a single-method contract

🔥 Pro Tip for Interviews

✅ If asked “Why only functional interfaces?”, say:

“Lambdas have no intrinsic type — they need a target type. Functional interfaces provide the functional descriptor that defines the lambda’s expected shape (parameters + return type). This makes type inference work and enables compile-time checks.”

✅ Mention:

  • This is part of “Target Typing” in Java.
  • Java avoids ambiguity by restricting lambdas to functional interfaces only.

🎯 Final Rule to Remember

“Lambda itself is just behavior. Functional interface provides the shape.”

This entry was posted in Без рубрики. Bookmark the permalink.