Learnitweb

Java Functional Interface

An interface with only single abstract method is called functional interface. A functional interface can contain default and static methods which do have an implementation in addition to single unimplemented method.

Functional interface acts as a type for lambda expression and can be used to invoke lambda expression

  • @FunctionalInterface annotation is added to declare interface as functional interface.
  • Use of @FunctionalInterface annotation is not compulsory for a functional interface, but use of @FunctionalInterface annotation helps in preventing additional abstract method accidentally.
  • Adding additional abstract method in an interface declared with @FunctionalInterface annotation will result in compilation error. 

There are some predefined Functional interfaces in Java. Following are some examples with their single abstract methods:

InterfaceSingle Abstract Method
public interface Consumer<T>void accept(T t)
public interface Function<T,R>R apply(T t)
public interface Predicate<T>boolean test(T t)
public interface Supplier<T>T get()
public interface Runnablevoid run()
public interface Callable<V>V call()
public interface ActionListenervoid actionPerformed(ActionEvent e)

You can also define a functional interface. For example, following is a functional interface:

interface Foo {
	public void play();
}

A functional interface can also have default and static methods. For example:

interface Foo {
	public void play();

	default void defaultPlay() {
		System.out.println("default play method");
	}

	public static void staticPlay() {
		System.out.println("static play method");
	}
}

In Java 8, Lambda expressions can represent the instance of a functional interface. For example:

Runnable r1 = () -> System.out.println(“Runnable example”);

@FunctionalInterface annotation

This annotation is used to indicate that an interface type declaration is intended to be a functional interface. As mentioned earlier, using this annotation is not mandatory with an interface intended to be a functional interface.

A functional interface has exactly one abstract method. A functional interface can have any number of default and static methods.

If user tries to add more than one abstract method, compiler will flag Invalid ‘@FunctionalInterface’ annotation message. For example, following interface is an invalid functional interface and will give compilation error. Here we have added another abstract method play2().

@FunctionalInterface
interface Foo {
	public void play();
	public void play2();
	default void defaultPlay() {
		System.out.println("default play method");
	}

	public static void staticPlay() {
		System.out.println("static play method");
	}
}

Functional interface with respect to inheritance

Case 1. If an interface extends functional interface and child interface does not contain any abstract method, then child interface is a functional interface.

In the following example, Child interface extends Parent interface. Child interface does not have its own method. So Child interface is a valid functional interface.

interface Parent {
	public void play();
}

@FunctionalInterface
interface Child extends Parent{
	
}

Case 2: If an interface extends functional interface and child interface defines the exact abstract method, then child interface will be a valid functional interface.

In the following example, child interface defines the same play() method. So child interface has only one abstract method, i.e. play(). So child interface is a valid functional interface.

interface Parent {
	public void play();
}

@FunctionalInterface
interface Child extends Parent{
	public void play();
}

Case 3: If an interface extends functional interface and child interface defines an additional abstract method then child interface is not a valid functional interface. However, child interface is a valid interface as it is possible for an interface to extend another interface.