Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V6081. Annotation that does not have...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V6081. Annotation that does not have 'RUNTIME' retention policy will not be accessible through Reflection API.

15 Июн 2020

Данное диагностическое правило позволяет обнаружить ошибочные ситуации, в которых при помощи Reflection API пытаются выявить наличие аннотаций, не имеющих политики удержания 'RUNTIME'.

Когда реализовывается аннотация, то ей необходимо прописать мета-аннотацию 'Retention', которая позволяет указать жизненный цикл аннотации:

  • RetentionPolicy.SOURCE – аннотации будут присутствовать только в исходном коде.
  • RetentionPolicy.CLASS - аннотации будут еще присутствовать в скомпилированном коде.
  • RetentionPolicy.RUNTIME - аннотации также будут видны в процессе выполнения программы.

Если вы 'Retention' не упоминали, то будет значение по умолчанию: 'CLASS'.

Используя Reflection API для получения информации о присутствующих аннотациях, необходимо учесть то, что только аннотации с политикой удержания 'RUNTIME' будут доступны механизму рефлексии. Любая попытка получить информацию о аннотации с политикой удержания 'SOURCE' или 'CLASS' ничего вам не даст.

Рассмотрим синтетический пример. В проекте реализована следующая аннотация:

package my.package;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ....})
public @interface MyAnnotation {
  int field_id() default -1;
  String field_name() default "";
  ....
}

Разработчик, пытаясь определить наличие этой аннотации у определенного метода через Reflection API:

void runMethod(Method method, ....)
{
  ....
  if (method.isAnnotationPresent(MyAnnotation.class))
  {
    ....
  }
  ....
}

всегда будет получать false. Это происходит из-за того, что при определении аннотации не использовали мета-аннотацию 'Retention'. А как ранее было уже сказано, что в случае, если ее не указывают, значение применяется по умолчанию: 'CLASS'.

Чтобы до вашей аннотации можно было достучаться через Reflection API, вам нужно будет явно об этом позаботиться, указав 'RUNTIME':

package my.package;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ....})
public @interface MyAnnotation {
  int field_id() default -1;
  String field_name() default "";
  ....
}

Помимо метода 'isAnnotationPresent', диагностическое правило проверяет: getAnnotation, getAnnotationsByType, getDeclaredAnnotation, getDeclaredAnnotationsByType.