Selft training repo
In Java, a Functional Interface is an interface that has exactly one abstract method. Functional Interfaces are a fundamental concept in functional programming and are a key part of Java’s support for lambda expressions and method references introduced in Java 8.
The @FunctionalInterface annotation is used to indicate that an interface is intended to be a functional interface. It is optional but serves as a safety mechanism to enforce the single abstract method rule. If an interface is annotated with @FunctionalInterface
1 and it contains more than one abstract method, the compiler will generate an error.
Functional Interfaces provide a convenient way to express behavior as data, which enables a more functional programming style in Java. They are widely used in Java libraries and APIs, especially when working with functional programming features like streams, predicates, consumers, suppliers, and more.
Here’s an example of a simple functional interface in Java:
@FunctionalInterface
interface MyFunctionalInterface {
void doSomething();
}
You can use lambda expressions or method references to implement the doSomething method concisely, like this:
MyFunctionalInterface myFunction = () -> System.out.println("Doing something!");
myFunction.doSomething(); // Output: "Doing something!"
Java 8 introduced a set of built-in functional interfaces in the java.util.function
package.
Since Java 8, interfaces can have “default” methods with implementations, but for an interface to be considered a Functional Interface, it must contain only one abstract method.
@FunctionalInterface
interface MyFunctionalInterface {
void doSomething(); // Abstract method
default void doSomethingElse() {
System.out.println("Doing something else!"); // Default method implementation
}
}
In this example, the MyFunctionalInterface still retains its SAM (Single Abstract Method), doSomething(). However, it now also includes a default method, doSomethingElse(), which has a default implementation.
Now, let’s create an implementing class:
class MyClass implements MyFunctionalInterface {
@Override
public void doSomething() {
System.out.println("Doing something!");
}
}
In this class, we override the doSomething() method, which is required because it’s the abstract method from the functional interface. However, we can choose to override the default method doSomethingElse() if we want to provide a custom implementation:
class MyClass implements MyFunctionalInterface {
@Override
public void doSomething() {
System.out.println("Doing something!");
}
@Override
public void doSomethingElse() {
System.out.println("Overridden: Doing something else differently!");
}
}
If we don’t override the default method doSomethingElse() in the implementing class, it will inherit the default implementation from the functional interface.
Let’s test the implementation:
public static void main(String[] args) {
MyFunctionalInterface myFunction = new MyClass();
myFunction.doSomething(); // Output: "Doing something!"
myFunction.doSomethingElse(); // Output: "Doing something else!"
}
As seen in the output, the overridden method doSomething() provides a custom implementation, while the default method doSomethingElse() is used as-is since it was not overridden in the MyClass implementation.
https://www.baeldung.com/java-8-lambda-expressions-tips https://www.baeldung.com/java-8-functional-interfaces
Get Started | Languages | Java Development | Java 8 | PF in Java
https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/FunctionalInterface.html ↩