2010-10-03 3 views
20

согласно аннотации Java API:Java аннотаций - ищет пример RetentionPolicy.CLASS

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

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

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

ответ

9

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

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

15

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

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

Examples on GitHub для вас, чтобы играть с.

+0

Если я декомпилирую класс с аннотацией 'RetentionPolicy.CLASS' (например,' @ VisibleForTesting' из Guava), то аннотация не будет отображаться в файле декомпилированного класса. Но согласно javadoc этот тип аннотации записывается в файл класса, а затем почему он не отображается в декомпилированном java-файле. Есть предположения? – tuk

Смежные вопросы