Java-аннотации - ищем пример RetentionPolicy.CLASS - PullRequest
21 голосов
/ 03 октября 2010

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

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

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

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

Ответы [ 4 ]

17 голосов
/ 16 августа 2012

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

11 голосов
/ 03 октября 2010

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

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

6 голосов
/ 28 июня 2013

RetentionPolicy.CLASS полезны при выполнении постобработки на уровне байтового кода.

Пример:

https://github.com/thesmythgroup/DroidCook/blob/master/src/org/tsg/android/api/Annotations.java

http://retroweaver.sourceforge.net/

1 голос

Минимальный пример

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 , с которыми вы можете играть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...