How does an annotation class differ from a normal class in Kotlin in terms of body, instantiation, and visibility?
answer
- no body vs full body
- compiler instantiates at @Name vs you call Name()
- public by default vs chosen visibility
- only annotations work after @
- annotations can't extend classes
basics
~10 sAn 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.
solid answer
~40 sAn `annotation class` is a constrained class form. It has **no body** (no methods, no init blocks, no nested behavior beyond allowed members), it is **implicitly public**, and you never instantiate it directly with a constructor call — the compiler builds the instance when you write `@Name(...)`. A normal `class` can hold state, define functions, have init logic, choose any visibility (private/internal/public), and is created via `Name()`. The `annotation` modifier also unlocks the `@` application syntax: only annotation classes can be used after `@`. Conversely, an annotation class cannot do many things a normal class does — it cannot have a non-primary-constructor body of functions, cannot extend another class, and its members are restricted. This makes it a pure metadata carrier rather than a behavioral type.
go deeper
Recalls that annotations have no body and you don't instantiate them like normal classes.
Lists the concrete differences: bodiless, compiler-instantiated, public, no inheritance, restricted members.
Explains why the language imposes these restrictions — pure metadata carrier — and how the @ gate works.
Reasons about the design tradeoffs of metadata-only types and how that shape supports tooling/reflection stability.
## The contrast at a glance | Aspect | `annotation class` | normal `class` | |---|---|---| | Body `{ }` | omitted / empty by design | usual body with functions, init | | Instantiation | done by compiler at `@Name(...)` site | `Name()` in your code | | Visibility | implicitly **public** | you choose (public/internal/private) | | Usable after `@` | yes | no | | Inheritance | cannot extend a class | can extend / implement | | Members | restricted (no arbitrary functions) | any members | ## No body An annotation is declared bodiless: ```kotlin annotation class Marker ``` You do **not** add functions or `init { }` blocks. Its purpose is to be metadata, not behavior. (Constructor **parameters** for annotation values exist, but that is a separate sibling topic; here the point is the *shape* has no behavioral body.) ## You don't `new` it You never write `val m = Marker()` to use it. Instead you apply it: ```kotlin @Marker class Service ``` The compiler synthesizes the annotation instance and stores it as metadata. (Reflectively, frameworks can obtain an instance, but that's reading, not your construction.) ## Implicitly public You never need (and shouldn't add) `public`: ```kotlin annotation class Marker // public // public annotation class Marker // redundant ``` A normal class lets you restrict visibility (`internal class Helper`); an annotation is public so it can be referenced wherever applied. ## The @ gate The `@Name` syntax is reserved for annotation classes. Try to write `@SomePlainClass` and it won't compile. The `annotation` modifier is what flips a type into this metadata role. ## Why the restrictions Because annotations exist only to be **attached and later read**, the language strips away class features that would imply behavior or state-at-runtime. This keeps them a predictable, serializable-into-class-metadata shape.
- Can an annotation class extend another class or implement an interface?No. Annotation classes cannot have a supertype list; they are a closed, metadata-only shape.
- If annotations have no body, how do they hold data like @Column(name = "id")?Through primary-constructor parameters (a sibling topic). The point here is they have no behavioral body of functions/init.
saying these in an interview costs you the question
- Saying you instantiate an annotation with a constructor in normal code to apply it
- Claiming annotation classes can have init blocks or member functions
- Believing annotations can extend a base class or implement interfaces
- Adding redundant `public` and thinking it is required
- Thinking a normal class can be used after @ with no annotation modifier