What are Functional Interfaces?
Functional interfaces are those interfaces that has single abstract method. According to Java 8 Specification, interface can be known as functional interface if there is a single method that is compliant with the below rules:
- If an interface has single abstract method, then it is known as the functional interface.
- A functional interface can have any number of default methods with single abstract method. Default methods are method declaration inside interfaces with the keyword “default”. This is one of the new feature from Java 8.
- If an interface extends another functional interface and not declaring any other methods in it, then it is considered as functional interface since it inherits single abstract method from the super interface.
- @FunctionalInterface annotation used by the compiler to detect if an interface is valid functional interface. It is not compulsory to use @FunctionalInterface annotation to indicate a functional interface.
- With addition to the single abstract method, it can declare any of the methods in Object class as abstract and still it is a valid functional interface.
- These interfaces are previously known as the Single Abstract Method Interfaces (SAMI).
- Few examples for the functional interfaces are, java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, java.util.concurrent.Callable
Examples for Functional Interfaces
Lets look at few examples that is part of Java API.
Runnable and Comparator interfaces is an example for the functional interface.
interface Runnable { void run(); }
Comparator.java
interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); }
Lets look at the below user defined interfaces with the functional interface semantics.
Deployable.java
package net.javabeat; public interface Deployable { boolean someWork(Iterable<String> arg); }
Integrateable.java
package net.javabeat; public interface Integrateable { boolean someWork(Iterable<String> arg); }
Useable.java
package net.javabeat; @FunctionalInterface public interface Useable extends Deployable, Integrateable{ }
- Useable is a functional interface because while it inherits two methods from Deployable and Integrateable. If you look at the both the interfaces, the methods have the same signature..So the inherited methods logically represent a single method.
- @FunctionalInterface annotation can be used at the top of the interface declaration.
Deployable.java
package net.javabeat; public interface Deployable { Iterable someWork(Iterable<String> arg); }
Instance Creation for Functional Interface
To create instances from your functional interfaces you have three ways:
- Create a class that implements your functional interface and just make an instance of that defined class. (Used Prior to Java 8).
- Create a method reference expression (Anonymous Instance, Used Prior to Java 8).
- Using Lambda expressions (New for Java 8).
Look at the below examples that would create instance of a given functional interface by using first and second options. Third option will be explained in the Lambda Expression section.
SomeInterface.java
package net.javabeat; public interface Deployable { Integer someWork(); }
UIComponent.java
package net.javabeat; public class UIComponent { public static void main(String [] args){ Deployable deployable = new Deployable() { @Override public Integer someWork() { return 1; } }; System.out.println("Invoke SomeWork Method Against SomeInterface :: "+deployable.someWork()); } }
The output will be:
Invoke SomeWork Method Against SomeInterface :: 1