>
>
>
V6081. Annotation that does not have 'R…


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

Данное диагностическое правило позволяет обнаружить ошибочные ситуации, в которых при помощи 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.