![]() | |
|
Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method (SAM), called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted.
All the existing single method interfaces like Runnable
,Callable
,
Comparator
, and ActionListener
in the JDK 8 are now functional interfaces and
lambdas can be used anywhere a single abstract method interface is used.
@FunctionalInterface annotation
Java 8 have introduced a new annotation @FunctionalInterface
to mark an interface as
such. It's basically to communicate intent but also allows the compiler to do some additional checks.
![]() | |
The |
For example, this interface compiles successfully:
public interface MyInterface { }
But when you indicate that it should be a functional interface:
// Java 8 compiler fails @FunctionalInterface public interface MyInterface { }
The compiler will raise an error as there is no abstract method. It says that "MyInterface
is
not a functional interface" as "no abstract method was found". It will also
error if we try and add a second method:
// Java 8 compiler fails ! @FunctionalInterface public interface MyInterface { void doIt(); void doItNow(); }
Default methods in interfaces
In Java 8 interfaces support default and static methods. A default method is an instance method
defined in an interface whose method header begins with the default
keyword; it
also provides a code body. Every class that implements the interface
inherits the interface's default methods and can override them.
Since functional interface requires a single abstract method, this code will NOT compile, as it is invalid functional interface:
// Java 8 compiler fails ! @FunctionalInterface public interface MyDefInterface { default void doIt() { /* cool implementation */ } }
But this functional interface will compile successfully:
@FunctionalInterface public interface MyDefInterface { default void doIt() { /* cool implementation */ } void doItNow(); // Single Abstract Method (SAM) }
Static methods in interfaces
A static method is a method that's associated with the class in which it's defined, rather than with any object created from that class. Every instance of the class shares the static methods of the class. Java 8 also lets static methods be defined in interfaces where they can assist default methods.
Like static methods in classes, you specify that a method definition in an interface is a
static method with the static
keyword at the beginning of the method signature. All method
declarations in an interface, including static methods, are implicitly public, so you can omit the
public
modifier.
When you implement an interface that contains a static method, the static method is still part of the interface and not part of the implementing class. For this reason, you cannot prefix the method with the class name. Instead, you must prefix the method with the interface name.
Since functional interface requires a single abstract method, this code will NOT compile, as it is invalid functional interface:
// Java 8 compiler fails ! @FunctionalInterface public interface MyStatInterface { static void doIt() { /* cool implementation */ } }
But this functional interface will compile successfully:
@FunctionalInterface public interface MyStatInterface { static void doIt() { /* cool implementation */ } void doItNow(); }
Public methods of java.lang.Object in functional interfaces
If an interface declares an abstract method overriding one of the public
methods of
java.lang.Object
, that also DOES NOT count toward the interface's abstract
method count since any implementation of the interface will have an implementation from
java.lang.Object
or elsewhere.
For example, java.util.Comparator
is a functional interface even though it declared two
abstract
methods:
package java.util; @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); ... }
The reason is because one of these abstract methods - equals()
- has signature identical to
public
method in java.lang.Object
class.
![]() ![]() ![]() |