Informally, a functional interface is one whose type can be used for a method parameter when a lambda is to be supplied as the actual argument. For example, the forEach
method on collections could have the following signature:
public void forEach(Consumer<? super T> consumer);
The implementation of forEach
must apply a single method of the Consumer
instance that has been supplied. This instance may be a lambda expression (see What is the type of a lambda expression?); if so, it will be applied in the place of that method. A lambda expression supplied in this way can take the place of only one interface method, so an interface can be used like this without ambiguity only if it has a single method.
More precisely, a functional interface is defined as any interface that has exactly one explicitly declared abstract method. (The qualification is necessary because an interface may have non-abstract default methods.) This is why functional interfaces used to be called Single Abstract Method (SAM) interfaces, a term that is still sometimes seen.
Examples
The following interfaces in the platform libraries (chosen from many) are functional interfaces according to the definition above:
public interface Runnable { void run(); }
public interface Callable<V> { V call() throws Exception; }
public interface ActionListener { void actionPerformed(ActionEvent e); }
public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
Syntax notes
- The interface
Comparator
is functional because although it declares two abstract methods, one of these—equals
— has a signature corresponding to a public method inObject
. Interfaces always declare abstract methods corresponding to the public methods ofObject
, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count. - [Skip this note on a first reading.] The situation is complicated by the possibility that two interfaces might have methods that are not identical but are related by erasure. For example, the methods of the two interfaces
interface Foo1 { void bar(List<String> arg); } interface Foo2 { void bar(List arg); }
are said to be override-equivalent. If the (functional) superinterfaces of an interface contain override-equivalent methods, the function type of that interface is defined as a method that can legally override all the inherited abstract methods. In this example, if
interface Foo extends Foo1, Foo2 {}
then the function type of
Foo
isvoid bar(List arg);
In fact, every functional interface has such a function type, though in the more common and simpler case it is just the single abstract method of that interface.
foreach
takes a function and applies
it to every element (see this page).
Leave a Reply