Какие политики сохранения (RetentionPolicy) существуют для аннотаций в Java?

«Какие политики сохранения (RetentionPolicy) существуют для аннотаций в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Аннотация @Retention определяет, на каком этапе жизненного цикла кода аннотация будет доступна. В Java существует три политики сохранения, задаваемые перечислением RetentionPolicy:

Политика Доступность Типичное использование
SOURCE Только в исходном коде. Удаляется компилятором и отсутствует в .class файле. @Override, @SuppressWarnings — для проверок на этапе компиляции.
CLASS (по умолчанию) Сохраняется в байт-коде (.class файл), но недоступна во время выполнения (JVM). Может использоваться инструментами для пост-обработки байт-кода (например, инструменты анализа).
RUNTIME Сохраняется в байт-коде и доступна во время выполнения через Reflection API. Аннотации для фреймворков (@Test в JUnit, @Controller в Spring), сериализации, кастомной логики.

Почему это важно? Выбор политики влияет на поведение программы и инструментов. Например, аннотации для Dependency Injection (как в Spring) должны быть RUNTIME, чтобы контейнер мог их прочитать и создать бины.

Пример объявления аннотации с политикой RUNTIME:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME) // Ключевая строка
public @interface LogExecution {
    String value() default "";
}

// Использование
@LogExecution("Service method")
public void processOrder() { /* ... */ }