Можно ли ясно объяснить практические различия между константами java.lang.annotation.RetentionPolicy
SOURCE
, CLASS
и RUNTIME
?
Я также не совсем уверен, что означает фраза "сохранение аннотации".
Можно ли ясно объяснить практические различия между константами java.lang.annotation.RetentionPolicy
SOURCE
, CLASS
и RUNTIME
?
Я также не совсем уверен, что означает фраза "сохранение аннотации".
RetentionPolicy.SOURCE
: Отменить во время компиляция. Эти аннотации не иметь смысл после компиляции завершены, поэтому они не байт-код.
Пример:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Отменить во время класс нагрузки. Полезно при выполнении пост-код-пост-обработки. Несколько удивительно, что это по умолчанию.
RetentionPolicy.RUNTIME
: Не отбрасывать. Аннотации должны быть доступный для отражения во время выполнения. Пример:@Deprecated
Источник:
Старый URL-адрес сейчас мертв
hunter_meta и заменен на hunter-meta-2-098036. Если даже это снижается, я загружаю изображение страницы.
Изображение (щелкните правой кнопкой мыши и выберите "Открыть изображение в новой вкладке/окне" )
Согласно вашим комментариям о декомпиляции класса, вот как я думаю, он должен работать:
RetentionPolicy.SOURCE
: не будет отображаться в декомпилированном классе
RetentionPolicy.CLASS
: Появляется в декомпилированном классе, но не может быть проверен во время выполнения с отражением с помощью getAnnotations()
RetentionPolicy.RUNTIME
: появляются в декомпилированном классе и могут быть проверены во время выполнения с отражением с помощью getAnnotations()
Минимальный пример runnable
Уровень языка:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionSource
class B {}
assert B.class.getAnnotations().length == 0;
@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.SOURCE
аннотированный .class
не получает никакой аннотации.
Примеры в GitHub для вас.
Политика хранения: политика хранения определяет, в какой момент аннотация будет отброшена.
1.SOURCE: annotation retained only in the source file and is discarded
during compilation.
2.CLASS: annotation stored in the .class file during compilation,
not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.
Политика хранения указывается с использованием встроенных аннотаций Java: @Retention.