Как различные политики хранения влияют на мои аннотации? - PullRequest
157 голосов
/ 24 июня 2010

Может ли кто-нибудь объяснить ясным образом практические различия между java.lang.annotation.RetentionPolicy константами SOURCE, CLASS и RUNTIME?

Я также не совсем уверен, что фраза "сохранение"аннотация »означает.

Ответы [ 5 ]

189 голосов
/ 24 июня 2010
  • RetentionPolicy.SOURCE: сброс во время компиляции.Эти аннотации не имеют никакого смысла после завершения компиляции, поэтому они не записываются в байт-код.
    Пример: @Override, @SuppressWarnings

  • RetentionPolicy.CLASS: Сбросить во время загрузки класса.Полезно при выполнении постобработки на уровне байт-кода.Несколько удивительно, что это значение по умолчанию.

  • RetentionPolicy.RUNTIME: не сбрасывать.Аннотация должна быть доступна для размышления во время выполнения.Пример: @Deprecated

Источник: Старый URL уже не работает hunter_meta и заменен на охотник-мета-2-098036 .Если даже это не помогло, я загружаю изображение страницы.

Изображение (Щелкните правой кнопкой мыши и выберите «Открыть изображение в новой вкладке / окне») Screenshot of Oracle website

47 голосов
/ 24 июня 2010

Согласно вашим комментариям о декомпиляции класса, вот как я думаю, что это должно работать:

  • RetentionPolicy.SOURCE: не появится в декомпилированном классе

  • RetentionPolicy.CLASS: появляются в декомпилированном классе, но не могут быть проверены во время выполнения с отражением с помощью getAnnotations()

  • RetentionPolicy.RUNTIME: появляются вдекомпилированный класс, и может быть проверен во время выполнения с помощью отражения getAnnotations()

18 голосов

Пример минимального запуска

Уровень языка :

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 weобратите внимание, что аннотированный класс Retention.CLASS получает атрибут класса RuntimeInvisible :

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()

, а аннотация Retention.RUNTIME получает атрибут класса RuntimeVisible :

#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()

и Runtime.SOURCE с аннотацией .class не получают никаких аннотаций.

Примеры на GitHub , с которыми можно играть.

4 голосов
/ 05 марта 2018

RetentionPolicy.SOURCE: аннотация будет доступна в исходном коде программы, она не будет ни в файле .class, ни будет доступна во время выполнения.Используется компилятором.RetentionPolicy.CLASS: аннотация будет в файле .class, но она не будет доступна во время выполнения.Используемые инструменты манипулирования байтовым кодом, такие как ASM, выполняют модификацииRetentionPolicy.RUNTIME: аннотация будет доступна в файле .class и во время выполнения для проверки с помощью java-отражения через getAnnotations().

3 голосов
/ 01 октября 2016

Политика хранения: политика хранения определяет, в какой момент аннотация аннулируется.

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.

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