If
you notice the above interface code, you will notice
@FunctionalInterface annotation. Functional interfaces are a new concept
introduced in Java 8. An interface with exactly one abstract method
becomes a Functional Interface. We don’t need to use
@FunctionalInterface annotation to mark an interface as a Functional
Interface.
Functional interfaces are new additions in java 8 which permit exactly one abstract method inside them. These interfaces are also called Single Abstract Method interfaces (SAM Interfaces).
@FunctionalInterface annotation is a facility to avoid
the accidental addition of abstract methods in the functional
interfaces. You can think of it like @Override annotation and it’s best
practice to use it. java.lang.Runnable with a single abstract method
run() is a great example of a functional interface.
One of the
major benefits of the functional interface is the possibility to
use lambda expressions to instantiate them. We can instantiate an
interface with an anonymous class but the code looks bulky.
Runnable r =
new
Runnable(){
@Override
public
void
run() {
System.out.println(
"My Runnable"
);
}};
Since
functional interfaces have only one method, lambda expressions can
easily provide the method implementation. We just need to provide method
arguments and business logic. For example, we can write above
implementation using lambda expression as:
If
you have single statement in method implementation, we don’t need curly
braces also. For example above Interface1 anonymous class can be
instantiated using lambda as follows:
So
lambda expressions are a means to create anonymous classes of
functional interfaces easily. There are no runtime benefits of using
lambda expressions, so I will use it cautiously because I don’t mind
writing a few extra lines of code.
A new package java.util.function
has been added with bunch of functional interfaces to provide target
types for lambda expressions and method references. Lambda expressions
are a huge topic, I will write a separate article on that in the future.
Important Points to be noted in Functional Interfaces:
1. only one abstract method is allowed in any functional interface. Second abstract method is not not permitted in a functional interface. If we remove @FunctionInterface annotation then we are allowed to add another abstract method, but it will make the interface non-functional interface.
2. This is valid even if we are not using @FunctionalInterface
annotation. It is only for informing the compiler to enforce single abstract method inside interface.
3. Addition of default methods to the functional interface is acceptable as long as there is
only one abstract method declaration:
You can follow the below example.
@FunctionalInterface
public interface Foo {
String method(String string);
default void defaultMethod() {}
}
4.