The reasoning is the same as for the @Override
annotation. The concept of Functional Interface has always existed in Java. It just didn't have a name. (It used to be informally called SAM (Single Abstract Method) Interface.)
So, there were already thousands of Functional Interfaces in the real world before the actual concept of Functional Interface was introduced. For example, the java.util.Comparator
interface is a Functional Interface in Java SE 13 but it already existed in Java 2 SE 5 and in fact was introduced as early as Java 1.2.
It's not the @FunctionalInterface
annotation that makes an interface a Functional Interface, it's the fact that it implements the Functional Interface specification.
Straight from the documentation (bold emphasis mine):
An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
and
However, the compiler will treat any interface meeting the Definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface
annotation is present on the interface declaration.
The presence or absence of the annotation is irrelevant to the interface being a Functional Interface. It only does two things:
- It tells the user of the interface that this is a Functional Interface.
- It tells the compiler to generate an error if the interface violates the Functional Interface Specification.
Again, this is a similar situation to the @Override
annotation. It's not the annotation that makes a method override another, it's the fact that you declare a method with the same name as a method in a supertype.