Пример минимального
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
Если мы используем javap
на аннотированных классов, мы видим, что Retention.CLASS
аннотированный класс получает атрибут в RuntimeInvisible класс:
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
в то время как Retention.RUNTIME
аннотацию получает атрибут в RuntimeVisible класс:
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
Так что информация присутствует на обоих случаях в байткод.
Следовательно, Runtime.CLASS
может использоваться для связывания произвольных метаданных с классом, который могут использоваться инструментами управления байт-кодом, без вмешательства в поведение во время работы.
Examples on GitHub для вас, чтобы играть с.
Если я декомпилирую класс с аннотацией 'RetentionPolicy.CLASS' (например,' @ VisibleForTesting' из Guava), то аннотация не будет отображаться в файле декомпилированного класса. Но согласно javadoc этот тип аннотации записывается в файл класса, а затем почему он не отображается в декомпилированном java-файле. Есть предположения? – tuk