An interface containing a single abstract method (SAM).
Ex:
Runnable: contains onlyrun()method.Comparable: contains onlycompareTo()method
The interface in addition to a single abstract method can have any number of default and static methods.
The restriction is only for a single abstract method.
Functional Interface
interface Interf{
//SAM(Single Abstract Method)
public abstract void m1();
//can have one or more default methods
default void m2(){
System.out.println("Hello");
}
//can have one or more static methods
static void m3(){
System.out.println("World");
}
}Not a Functional Interface
interface Interf{
//more than one abstract method
public abstract void m1();
public abstract void m2();
}interface Interf{
//no abstract method
}In Java 8, @FunctionalInterface annotation was introduced to specify functional interfaces.
Used to explicitly indicate an interface is Functional interface.
This helps to enforce compile time checking on presence of exactly one abstract method and prevents accidental addition of additional abstract methods in a declared Functional Interface.
Ex:
@FunctionalInterface
interface Interf{
//Single Abstract Method
void m1();
}-
Inside a
@FunctionalInterfaceannotated interface, there can be only one abstract method, if more than one abstract method is defined then compiler throws compilation error:unexpected @FunctionalInterface annotation.
Multiple non-overriding abstract methods present in interface InterfaceName -
Inside a
@FunctionalInterfaceannotated interface, it is mandatory to declare one abstract method. If not declared compiler throws compilation error:unexpected @FunctionalInterface annotation.
no abstract method found in interface InterfaceName.
So, @FunctionalInterface enables compile time checking for Functional interfaces and makes the code more robust.
It basically acts as a contract for an interface to follow the Single Abstract Method Rule.
In case an interface extends a Functional Interface. And the child interface doesn't contain any abstract method then the
child interface is also a Functional interface. (As it will inherit the Single Abstract Method)
Ex:
@FunctionalInterface
interface A{
public void m1();
}
@FunctionalInterface
interface B extends A{
}The child interface can contain exactly same abstract method as parent, and it would still remain Functional Interface (override parent's declaration).
Ex:
@FunctionalInterface
interface A{
public void m1();
}
@FunctionalInterface
interface B extends A{
public void m1();
}In the child interface we can't define any new abstract method if @FunctionalInterface
is applied to it else it will throw compilation error.
Ex:
@FunctionalInterface
interface A{
public void m1();
}
@FunctionalInterface
interface B extends A{
//compilation error
public void m2();
}compilation error:
Unexpected @FunctionalInterface annotation.
multiple non-overriding abstract methods found in interface B
- But if
@FunctionalInterfaceis dropped, new abstract methods can be defined in the child interface; but the child interface won't be Functional Interface anymore.
Ex:@FunctionalInterface interface A{ public void m1(); } //normal interface not Functional Interface. interface B extends A{ //no compilation error //new abstract method public void m2(); }
Note:
Functional Interfaces can be used to invoke Lambda Expressions. It acts as a type for Lambda Expression, thus can refer a Lambda Expression. And the Single Abstract Method is used for the invokation.