skip to content

Meta-Annotations & @Repeatable

Meta-annotations configure other annotations — retention, targets, documentation — and @Repeatable allows the same one several times on a declaration. They are the vocabulary you need to design an annotation rather than just apply one.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What are meta-annotations in Kotlin, and which built-in ones can you place on an annotation declaration?

level: juniorimportance: must knowfreq 55%

answer

  1. Annotation on an annotation class
  2. Four: @Target, @Retention, @MustBeDocumented, @Repeatable
  3. All live in kotlin.annotation
  4. @Target = where, @Retention = how long
  5. Default retention is RUNTIME

basics

~10 s

Meta-annotations are annotations you put on another annotation's declaration to describe how it behaves. The built-in ones are @Retention, @Target, @MustBeDocumented, and @Repeatable.

solid answer

~30 s

A meta-annotation is an annotation applied to an annotation class declaration (an `annotation class`). Kotlin ships four in `kotlin.annotation`: `@Target` restricts which code elements the annotation may be applied to (e.g. `AnnotationTarget.CLASS`, `FUNCTION`, `PROPERTY`); `@Retention` controls how long it is kept — `SOURCE`, `BINARY`, or `RUNTIME` (default is `RUNTIME`, unlike Java's default of `CLASS`/binary); `@MustBeDocumented` marks it as part of the public API so it appears in generated docs; and `@Repeatable` allows the same annotation to be applied more than once to a single declaration. These configure metadata, not runtime logic, and are read by the compiler and by reflection.

code

kotlin · 7 lines
kotlin
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Benchmark

@Benchmark
fun runHotPath() { /* ... */ }

go deeper

for a junior

Names all four built-in meta-annotations and states each one's purpose in a sentence.

for a middle

Knows the package (kotlin.annotation), the default retention (RUNTIME), and that targets are enforced by the compiler.

for a senior

Explains the Java interop mapping and that behavior lives in the reader, not the annotation; contrasts Kotlin vs Java defaults.

for a principal

Discusses API-design implications: choosing retention/target to keep annotations honest and processable, and how @MustBeDocumented affects published API surface.

## What "meta-annotation" means An **annotation** is a marker you attach to code (classes, functions, properties, parameters) to carry metadata. A **meta-annotation** is simply an annotation that you attach to *another annotation's declaration* — that is, to an `annotation class`. It configures how that annotation behaves rather than configuring ordinary code. The four built-in meta-annotations live in the package `kotlin.annotation`: - **`@Target(vararg allowedTargets: AnnotationTarget)`** — restricts *where* your annotation may legally be used. Values come from the `AnnotationTarget` enum: `CLASS`, `FUNCTION`, `PROPERTY`, `FIELD`, `VALUE_PARAMETER`, `TYPE`, `EXPRESSION`, `FILE`, and more. If you omit `@Target`, the annotation is allowed on almost all targets. - **`@Retention(value: AnnotationRetention)`** — controls how long the annotation is kept: `SOURCE` (discarded by the compiler), `BINARY` (kept in the `.class` file but not visible to reflection), or `RUNTIME` (kept and visible to reflection). **Kotlin's default is `RUNTIME`.** - **`@MustBeDocumented`** — signals that the annotation is part of the element's public API and should be included in generated API documentation (e.g. Dokka). It takes no arguments. - **`@Repeatable`** — allows the same annotation to appear multiple times on one declaration. ## Example ```kotlin @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) @MustBeDocumented annotation class Audited(val reason: String) @Audited("compliance") class PaymentService ``` Here `Audited` is an annotation **class**, and `@Target`, `@Retention`, and `@MustBeDocumented` are meta-annotations describing it. ## Why it matters Meta-annotations are pure configuration read by the **compiler** (to enforce targets) and by **reflection / annotation processors** (to read values at the chosen retention). They contain no executable logic themselves.

  • Are these meta-annotations Kotlin-specific or shared with Java?
    They are Kotlin's own (`kotlin.annotation.*`). Java has analogous `@Target`, `@Retention`, `@Documented`, `@Repeatable` in `java.lang.annotation`. The Kotlin compiler maps Kotlin annotations to the Java forms where needed for interop, but the defaults differ — notably Kotlin defaults retention to RUNTIME.
  • Do meta-annotations contain runtime behavior?
    No. They only declare metadata that the compiler enforces and reflection/processors read. Any actual behavior (logging, validation) lives in the code that *reads* the annotation, not in the annotation itself.

Like a label on a label-maker: it doesn't tag a product, it configures how the labels you print will behave.

saying these in an interview costs you the question

  • Thinking meta-annotations execute code at runtime
  • Listing only @Target and @Retention, forgetting @MustBeDocumented and @Repeatable
  • Saying Kotlin's default retention is BINARY/CLASS (that's Java)
  • Confusing an annotation use with an annotation declaration
  • Claiming you must always specify @Target

context

open as a page

How do AnnotationRetention values (SOURCE, BINARY, RUNTIME) interact with reading meta-configured annotations, and what is Kotlin's default?

level: seniorimportance: must knowfreq 40%

basics

~10 s

@Retention sets how long an annotation survives: SOURCE (compile-time only), BINARY (in the class file), or RUNTIME (readable by reflection). Kotlin defaults to RUNTIME.

open as a page

What does @Repeatable do, and how do you declare and apply a repeatable annotation in Kotlin?

level: middleimportance: should knowfreq 45%

basics

~10 s

@Repeatable lets you put the same annotation on one declaration more than once. You mark the annotation class with @Repeatable, then apply it multiple times.

open as a page

How does @Target govern annotation placement, what happens if you omit it, and how does it interact with @Repeatable for a multi-target annotation?

level: seniorimportance: should knowfreq 35%

basics

~10 s

@Target lists the kinds of code an annotation may be put on. Omit it and the annotation is allowed on most targets. Using it on a disallowed target is a compile error.

open as a page

What is @MustBeDocumented for, and how does it differ from @Retention and @Target in effect?

level: middleimportance: nice to knowfreq 25%

basics

~10 s

@MustBeDocumented marks an annotation as part of an element's public API so documentation tools include it. It changes docs only — not where the annotation can go or how long it's kept.

open as a page