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().
Ответ 3
RetentionPolicy.CLASS полезны при выполнении пост-обработки на байтовом уровне кода.
Пример:
https://github.com/thesmythgroup/DroidCook/blob/master/src/org/tsg/android/api/Annotations.java
http://retroweaver.sourceforge.net/
Ответ 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 для вас.