Почему @FunctionalInterface имеет срок хранения RUNTIME?

Указано в Javadoc:

Если тип аннотирован этим типом аннотации, компиляторы должны генерировать сообщение об ошибке, если...

Почему недостаточно SOURCE или CLASS, например, для @Override.


person auntyellow    schedule 25.11.2014    source источник


Ответы (3)


Аннотация @FunctionalInterface служит двум целям. Что касается компилятора и ошибки, которую он должен генерировать, было бы действительно достаточно иметь SOURCE RetentionPolicy, так как в этом отношении он влияет только на тот самый класс, аннотированный @FunctionalInterface.

Однако у него есть вторая цель, документирование того факта, что использование этого interface в качестве функционального интерфейса действительно предусмотрено, и возможность использовать его таким образом не просто совпадение, как, например, с. Comparable который не предназначен для использования таким образом.

Поэтому он помечен @Documented и имеет максимум RetentionPolicy для выполнения второй цели.

person Holger    schedule 25.11.2014
comment
Есть ли у каждого интерфейса @Documented максимальная RetentionPolicy (RUNTIME)? - person auntyellow; 25.11.2014
comment
@auntyellow: Это несложное требование, однако его цель сделать информацию широко доступной приводит к выводу, что вы обычно хочете максимального удержания. Кстати, RetentionPolicy.CLASS не дает никаких преимуществ перед RUNTIME. Он занимает столько же места в файле класса, и, поскольку Reflection загружает аннотации только по запросу, нет никакой выгоды в том, что он недоступен во время выполнения. - person Holger; 25.11.2014

«Источника» будет недостаточно, поскольку, например, если вы создадите API и предоставите свой класс в виде предварительно скомпилированного jar, информация больше не будет доступна для компилятора.

Я считаю, что «класса» также будет недостаточно, если вы хотите поддерживать такие компиляторы, которые «компилируют» класс во время выполнения, например механизмы сценариев, которые используют отражение, чтобы узнать об этих аннотациях, и также должны показывать предупреждение.

person Sebastian    schedule 25.11.2014

@FunctionalInterface предназначен для отражения времени выполнения, проверки компиляции и, возможно, процесса выполнения Java.

javap используется для декомпиляции и сравнения двух интерфейсов, один с @FunctionalInterface, другой без него.

Просто дополнительные две строки байтового кода в интерфейсе с тегом @FunctionalInterface:

Constant pool:
   #7 = ...   RuntimeVisibleAnnotations
   #8 = ...   Ljava/lang/FunctionalInterface;

И реализация/лямбда-экспресс одинаковы на уровне байтового кода.

За исключением отражения интерфейса:

X.class.getAnnotation(FunctionalInterface.class) == null?;
person 卢声远 Shengyuan Lu    schedule 25.11.2014