Why is this an issue?

Denoted by the "@" symbol, annotations are metadata that can be added to classes, methods, and variables for various purposes such as documentation, code analysis, and runtime processing.

Annotations have retention policies that determine in which context they are retained and available for use. There are three retention policies for annotations:

It is important to understand that only annotations having the RUNTIME retention policy can be accessed at runtime using reflection. For example, the following if condition is true when the method argument is the java.util.function.Function class:

void execute(Class<?> cls) {
  if (cls.isAnnotationPresent(FunctionalInterface.class)) {
    // ...
  }
}

Therefore, it is an issue to use reflection in combination with annotations with the SOURCE or CLASS retention policy because they are not present at runtime. For example, in the JVM source code, the hashCode() method of the Integer class has the @Override annotation. However, the following if condition will always be false even if the method argument is the Integer#hashCode() method because @Override has the SOURCE retention policy:

void execute(Method method) {
  if (method.isAnnotationPresent(Override.class)) { // Noncompliant, if condition will always be false because
                                                    // @Override is declared with @Retention(RetentionPolicy.SOURCE)
    // ...
  }
}

This rule detects improper reflective access on annotations having the SOURCE or CLASS retention policy.

Resources

Documentation