Аннотации для ограничения вариантов

В Kotlin (и Java) аннотация @Retention используется для указания времени жизни аннотации, то есть, насколько долго аннотация должна быть доступна. Существуют три типа Retention, каждый из которых имеет свои особенности и используется в различных случаях

Retention.SOURCE:

  • Описание: Аннотация сохраняется только в исходном коде и отбрасывается во время компиляции.
  • Использование: Используется для аннотаций, которые нужны только на этапе компиляции, например, для статического анализа кода, генерации кода, проверки кода на соответствие каким-то правилам.
  • Пример: @Override в Java, @StringDef в Kotlin/Java.
@Retention(AnnotationRetention.SOURCE)
annotation class ExampleSourceAnnotation

Retention.CLASS (по умолчанию в Java):

  • Описание: Аннотация сохраняется в байт-коде, но недоступна во время выполнения.
  • Использование: Подходит для аннотаций, которые нужны на этапе компиляции и связывания, но не нужны во время выполнения. Это также полезно для инструментов, работающих с байт-кодом, таких как инструменты для анализа байт-кода.
  • Пример: Некоторые аннотации для фреймворков, которые используются на этапе компиляции.
@Retention(AnnotationRetention.BINARY)
annotation class ExampleClassAnnotation

Retention.RUNTIME

  • Описание: Аннотация сохраняется в байт-коде и доступна во время выполнения через рефлексию.
  • Использование: Применяется для аннотаций, которые нужны во время выполнения программы, например, для DI (Dependency Injection) фреймворков, ORM (Object-Relational Mapping), сериализации, тестовых фреймворков и других механизмов, которые требуют доступа к аннотациям в runtime.
  • Пример: Аннотации как @Deprecated, @Override (в Kotlin), @Entity в JPA.
@Retention(AnnotationRetention.RUNTIME)
annotation class ExampleRuntimeAnnotation

Когда использовать каждый вид Retention

  • Retention.SOURCE:
    • Используйте, когда аннотация должна помочь разработчику на этапе написания кода и компиляции, но не нужна в скомпилированном коде.
    • Примеры: проверка кода на соответствие стилю, генерация кода, документация.
  • Retention.CLASS:
    • Используйте, когда аннотация должна быть доступна во время компиляции и связывания, но не требуется во время выполнения.
    • Примеры: инструменты анализа байт-кода, проверка кода на этапе компиляции.
  • Retention.RUNTIME:
    • Используйте, когда аннотация должна быть доступна во время выполнения через рефлексию.
    • Примеры: фреймворки для инверсии управления (DI), ORM, сериализация данных, тестовые фреймворки.

Применение правильного уровня Retention помогает оптимизировать использование ресурсов и повышает читаемость и поддержку кода.