Meta-Annotations in Java — @Retention, @Target, @Documented, @Inherited Explained
Fast recall
Quick revision
Core answer
SOURCE, CLASS, RUNTIME); `@Target` — which program elements can carry it (TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR, ANNOTATION_TYPE, etc.); `@Documented` — include in Javadoc output; `@Inherited` — subclasses inherit the annotation from the parent class. Java 8+ adds `@Repeatable`. Retention policies: SOURCE = discarded by compiler (Lombok, @Override); CLASS = in bytecode but not loaded (default; tools); RUNTIME = available via reflection (Spring @Autowired, JUnit @Test).Whether the candidate knows all four meta-annotations, can distinguish the three retention policies with concrete examples, and knows what happens at each phase
Confusing CLASS and RUNTIME (both are in .class files; only RUNTIME is readable via reflection). Not knowing `@Inherited` only works for classes, not methods/fields. Forgetting that @Target with no args allows all locations
Give the compiler phase for each retention: SOURCE discarded after javac; CLASS in .class but not loaded to VM; RUNTIME loaded and reflection-readable. Mention @Repeatable (Java 8+) for multiple instances of the same annotation on one element
Interview-ready guide
Interview answer
Meta-annotations are annotations that apply to other annotations — they control how the annotation behaves.
The four main meta-annotations
- `@Retention` — when the annotation is preserved
- `@Target` — where it can be applied
- `@Documented` — whether it shows up in Javadoc
- `@Inherited` — whether subclasses inherit it from parent classes
- Java 8+ adds `@Repeatable` for applying the same annotation multiple times
The three retention policies — pick based on when the annotation matters
- `SOURCE` — discarded by the compiler; not in bytecode. Used for compile-time processing: Lombok
@Getter,@Override,@SuppressWarnings - `CLASS` (default) — in the
.classfile but not loaded by the JVM at runtime. Used by bytecode analysis tools like SpotBugs - `RUNTIME` — loaded and readable via reflection. Required for any framework annotation that drives runtime behavior: Spring
@Autowired, JUnit@Test, Jackson@JsonProperty, Hibernate@Entity
`@Target` locations
TYPE,METHOD,FIELD,PARAMETER,CONSTRUCTOR,ANNOTATION_TYPE,PACKAGE,LOCAL_VARIABLE- Java 8 added
TYPE_PARAMETERandTYPE_USEfor annotations on generic type parameters and any type use - The compiler enforces
@Target— applying in a disallowed location is a compile error
`@Inherited` is subtle
- Only applies to class-level annotations — subclasses automatically carry the annotation from the parent
- Methods and fields never inherit annotations regardless of
@Inherited
`@Repeatable` pattern
- Define a container annotation with a
value()returning an array of the repeatable type - Mark the base annotation
@Repeatable(Container.class) - Read at runtime with
getAnnotationsByType()instead ofgetAnnotation()
Recommendation: For any framework-style annotation that drives runtime behavior, use @Retention(RUNTIME) + @Target(specific locations) + @Documented. Skip @Inherited unless you specifically want class-level inheritance behavior — most frameworks do their own discovery logic. Use @Repeatable when you legitimately need multiple instances on the same element (schedules, validation groups), not as a workaround for poor API design.
Meta-Annotations in Java — `@Retention`, `@Target`, `@Documented`, `@Inherited` Explained
Direct Answer
Meta-annotations are annotations applied to other annotations to control how they're used. The four main ones: @Retention — when the annotation is preserved (SOURCE, CLASS, RUNTIME); @Target — which program elements can carry it (TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR, ANNOTATION_TYPE, etc.); @Documented — include in Javadoc output; @Inherited — subclasses inherit the annotation from the parent class. Java 8+ adds @Repeatable. Retention policies: SOURCE = discarded by compiler (Lombok, @Override); CLASS = in bytecode but not loaded (default; tools); RUNTIME = available via reflection (Spring @Autowired, JUnit @Test).
Common Mistakes & Pitfalls
Confusing CLASS and RUNTIME (both are in .class files; only RUNTIME is readable via reflection). Not knowing @Inherited only works for classes, not methods/fields. Forgetting that @Target with no args allows all locations
Check your understanding
Answer these without looking back at the article.
- What's the practical difference between `@Retention(CLASS)` and `@Retention(RUNTIME)`?
- Why does `@Inherited` only work on class-level annotations?
- How does `@Repeatable` work internally — what does the container annotation look like in bytecode?
- What's the difference between `ElementType.TYPE_PARAMETER` and `ElementType.TYPE_USE`?
- Why is `CLASS` the default retention, not `RUNTIME`?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.