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.