Java Annotations - поиск примера RetentionPolicy.CLASS

в соответствии с API аннотации Java:

  • RetentionPolicy.CLASS       Аннотации должны быть записаны в файле класса с помощью компилятор, но не нужно VM во время выполнения.

  • RetentionPolicy.RUNTIME       Аннотации должны быть записаны в файле класса с помощью компилятор и сохраняемый VM при запуске времени, поэтому они могут быть прочитаны рефлекторно.

Я ищу образец политики хранения "CLASS". когда нам нужно использовать эту политику вместо политики RUNTIME.

Ответ 1

Из всего большого количества библиотек, которые у меня есть в моем текущем проекте. единственные примеры, которые я могу найти, находятся в Google Guava, например com.google.common.annotations.GwtCompatible.

Я не уверен, почему они выбрали эту политику хранения, хотя, возможно, для поддержки инструментов, где инструменты читают сами файлы классов, а не проходят через API отражения. Я не уверен, что я действительно вижу смысл этого различия.

Ответ 2

КЛАСС Аннотации используются в инструментах обфускатора, таких как http://proguard.sourceforge.net. Например, аннотация @KeepName отключает манипулирование именами, когда вам нужно, чтобы ваше имя класса не изменялось, чтобы иметь возможность вызывать методы типа Class.forName().

Ответ 4

Минимальный пример того, как он работает по-другому на языке:

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

Примеры в GitHub для вас.