Аннотации @FunctionalInterface
служат для двух целей. Что касается компилятора и ошибки, которую он должен сгенерировать, было бы достаточно, чтобы иметь SOURCE
RetentionPolicy
, поскольку в этом отношении он влияет только на сам класс, аннотированный с помощью @FunctionalInterface
.
Однако это имеет вторую цель, документируя тот факт, что использование этого interface
в качестве функционального интерфейса действительно предназначено и возможность использовать его таким образом, а не просто совпадение, например, с, например, Comparable
, который не предназначен для использования таким образом.
Поэтому он аннотируется с @Documented
и имеет максимальную RetentionPolicy
для выполнения второй цели.
«Source» будет недостаточно, поскольку, если вы, например, создаете API и предоставляете свой класс в качестве предварительно скомпилированного jar, информация больше не будет доступна для компилятора.
Я считаю, «class» также не будет достаточным, если вы хотите поддержать тех компиляторов, которые «компилируются» против класса во время выполнения, например, для сценариев, которые используют рефлексию, чтобы узнать об этих аннотациях и также должны показать предупреждение.
@FunctionalInterface
предназначен для проверки выполнения, проверки компиляции и процесса выполнения Java.
javap используется для декомпилирования и сравнения двух интерфейсов, один с @FunctionalInterface
, а другой нет.
Только лишний байтовый код двух строк в интерфейсе с меткой @FunctionalInterface
:
Constant pool:
#7 = ... RuntimeVisibleAnnotations
#8 = ... Ljava/lang/FunctionalInterface;
И оба варианта реализации / лямбда-выражения одинаковы на уровне байтового кода.
За исключением отображения интерфейса:
X.class.getAnnotation(FunctionalInterface.class) == null?;