What are meta-annotations in Kotlin, and which built-in ones can you place on an annotation declaration?
answer
- Annotation on an annotation class
- Four: @Target, @Retention, @MustBeDocumented, @Repeatable
- All live in kotlin.annotation
- @Target = where, @Retention = how long
- Default retention is RUNTIME
basics
~10 sMeta-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 sA 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@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Benchmark
@Benchmark
fun runHotPath() { /* ... */ }go deeper
Names all four built-in meta-annotations and states each one's purpose in a sentence.
Knows the package (kotlin.annotation), the default retention (RUNTIME), and that targets are enforced by the compiler.
Explains the Java interop mapping and that behavior lives in the reader, not the annotation; contrasts Kotlin vs Java defaults.
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