RetentionPolicy CLASS против RUNTIME

Какова практическая разница между RetentionPolicy.CLASS и RetentionPolicy.RUNTIME?

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

Ответ 1

оба могут быть доступны во время выполнения в любом случае.

Это не то, что javadoc говорит:

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

КЛАСС: Аннотации должны записываться в файл класса компилятором, но не нужно сохранять VM во время выполнения.

На практике я не знаю о случаях использования для CLASS. Это было бы полезно, если бы вы хотели читать байт-код программно, в отличие от API-интерфейса classloader, но это очень специализированный случай, и я не знаю, почему вы просто не использовали бы RUNTIME.

По иронии судьбы, CLASS - это поведение по умолчанию.

Ответ 2

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

False для базовых встроенных аннотационных интерфейсов, таких как getAnnotations. Например:.

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;
}

поэтому единственный способ наблюдения аннотации RetentionPolicy.CLASS - использование парсера байт-кода.

Другое отличие состоит в том, что класс Retention.CLASS с аннотацией получает атрибут RuntimeInvisible, а Retention.RUNTIME аннотации получают RuntimeVisible атрибут класса. Это можно наблюдать с помощью javap.

Примеры в GitHub для вас.

Ответ 3

Политика хранения[About]

Аннотации с политикой хранения CLASS и RUNTIME доступны из байтового кода класса. Нам нужно использовать библиотеку манипулирования байтовым кодом (например, ASM) для доступа к аннотациям, доступным в байтовом коде.

Простой пример здесь