Precise definition of "functional interface" in Java 8
An interface cannot extend Object class, because Interface has to have public and abstract methods.
For every public method in the Object class, there is an implicit public and abstract method in an interface.
This is the standard Java Language Specification which states like this,
“If an interface has no direct super interfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.”
That's how Object class' methods are declared in an interface. And according to JLS, this does not count as interface' abstract method. Hence, Comparator interface is a functional interface.
Q. But in the Comparator interface both compare() and equals() methods are abstract, which means it has two abstract methods. So how can this be working, if the definition requires an interface to have exactly one abstract method? What am I missing here?
A.
A functional interface may specify any public method defined by Object, such as equals( ), without affecting its “functional interface” status. The public Object methods are considered implicit members of a functional interface because they are automatically implemented by an instance of a functional interface.
Another explanation is given in the @FunctionalInterface page:
Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. 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 fromjava.lang.Object
or elsewhere.
You can test which interface is a correct functional interface using @FunctionalInterface
.
E.g.:
this works
@FunctionalInterface public interface FunctionalInterf { void m(); boolean equals(Object o); }
this generates an error:
@FunctionalInterface public interface FunctionalInterf { void m(); boolean equals(); }
Multiple non-overriding abstract methods found in interface FunctionalInterf
From the same page you linked to:
The interface Comparator is functional because although it declares two abstract methods, one of these—equals— has a signature corresponding to a public method in Object. Interfaces always declare abstract methods corresponding to the public methods of Object, but they usually do so implicitly. Whether implicitly or explicitly declared, such methods are excluded from the count.
I can't really say it better.