skip to content

Declaring Annotations

An annotation is declared with the annotation class modifier and applied with @Name. It is deliberately a restricted kind of class, which is why the parameter rules that follow are so narrow.

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

questions

5

How do you declare your own annotation in Kotlin, and how do you apply it to a function?

level: juniorimportance: must knowfreq 60%

answer

  1. annotation class Name
  2. apply with @Name
  3. implicitly public, no body
  4. @ only accepts annotation classes
  5. metadata, read later by tools/reflection

basics

~10 s

Write a class with the annotation class keywords, for example annotation class Loggable. Then put @Loggable in front of a function, property, or class to mark it.

solid answer

~40 s

You declare an annotation with the annotation class modifier: `annotation class Loggable`. This special class form has no body and no instances you create with a constructor; the compiler treats it as metadata. You apply it by prefixing a declaration with @ plus the name: `@Loggable fun run() { ... }`. The name after @ is the annotation class name. Annotations are implicitly public, can be top-level, and need no `class` body braces. Applying one attaches metadata that tools, frameworks (Spring, JUnit), or your own reflection code can later read. Without the `annotation` modifier you'd have an ordinary class that cannot be used with @ syntax.

code

kotlin · 9 lines
kotlin
annotation class Loggable

@Loggable
fun process() {
    println("work")
}

@Loggable
class Worker

go deeper

for a junior

Knows the annotation class keyword and that you apply it with @Name on a declaration.

for a middle

Explains it is implicitly public, bodiless, and distinct from a normal class that the @ syntax rejects.

for a senior

Frames annotations as metadata consumed by compiler/tools/reflection and can contrast plain class vs annotation class precisely.

for a principal

Discusses design intent of metadata-only types, how frameworks discover them, and conventions for declaring a small annotation surface.

## What an annotation is An **annotation** is a marker you attach to code (classes, functions, properties, parameters) that carries **metadata** — extra information that doesn't change runtime logic by itself but can be read by the compiler, build tools, or frameworks. ## Declaring one You use the **`annotation class`** modifier combination: ```kotlin annotation class Loggable ``` That's a complete, valid declaration. `annotation` is a soft modifier in front of `class`. Key points: - It can be **top-level** (file scope) or nested. - It is **implicitly `public`** — you don't write `public`. - It typically has **no body**; the braces `{ }` are omitted. ## Applying one You put `@` immediately before the annotation name on the target declaration: ```kotlin @Loggable fun run() { /* ... */ } @Loggable class Service @Loggable val name: String = "x" ``` The identifier after `@` must resolve to an `annotation class`. You can apply the **same** annotation to many declarations. ## Why `annotation class` and not plain `class` A normal `class Loggable` is an ordinary type: you instantiate it with `Loggable()`, it can hold state, have functions, etc. You **cannot** write `@Loggable` with a plain class — the `@` syntax only accepts annotation classes. The `annotation` modifier tells the compiler this type's sole purpose is to be used as an annotation. ## Naming convention Annotation names use **PascalCase** like other types (`@Loggable`, `@JsonField`), unlike functions. ## Summary `annotation class Name` declares it; `@Name` applies it; it is public and bodiless by design.

  • Can you apply @Loggable if you declared it as a plain `class Loggable`?
    No. The @ application syntax requires an annotation class. A plain class is not usable with @, so it won't compile as an annotation.
  • Do you need to write `public` before `annotation class`?
    No. Annotation classes are public by default like other top-level declarations, so the modifier is redundant.

An annotation is like a sticky note on a document: it doesn't change the text, but anyone reading later can act on what the note says.

saying these in an interview costs you the question

  • Saying you create annotations with plain `class` and no `annotation` modifier
  • Claiming you instantiate an annotation with a constructor call like Loggable() to apply it
  • Confusing applying (@Name) with declaring (annotation class Name)
  • Thinking annotations change runtime behavior automatically without anything reading them

context

open as a page

How does an annotation class differ from a normal class in Kotlin in terms of body, instantiation, and visibility?

level: middleimportance: must knowfreq 45%

basics

~10 s

An annotation class has no body, you don't create it with new/constructor calls in your code, and it's public by default. A normal class has a body, is instantiated, and you choose its visibility.

open as a page

What kinds of declarations can you apply a self-declared annotation like @Loggable to, and what does applying it actually do at runtime by default?

level: middleimportance: should knowfreq 35%

basics

~10 s

You can put @Loggable on classes, functions, properties, parameters, and more. By itself it does nothing at runtime — it just marks the code so something else can read and react to the mark.

open as a page

What does an `annotation class` compile to on the JVM, and why does its 'implicitly public, no-body' shape matter for interop and tooling?

level: seniorimportance: should knowfreq 22%

basics

~20 s

On the JVM a Kotlin annotation class becomes a Java annotation type (an interface-like @interface). Its public, bodiless shape means Java and tools can see and use it the same way they use Java annotations.

open as a page

You're designing a small set of marker annotations for your codebase. What principles guide declaring them, and what mistakes turn an annotation into a poor abstraction?

level: seniorimportance: nice to knowfreq 14%

basics

~20 s

Keep each annotation a small, clearly named public marker that means one thing, and make sure something actually reads it. Avoid using an annotation when a normal type, interface, or function would express the idea better.

open as a page