What does @Target do, and what happens if a custom annotation has no @Target?
answer
- @Target = WHERE; @Retention = HOW LONG
- Values come from ElementType
- No @Target = applicable everywhere
- Compile-time rejection of misuse
- TYPE_USE / TYPE_PARAMETER are Java 8
basics
~10 s@Target restricts which program elements an annotation can be placed on, like methods or fields, using ElementType values. With no @Target, the annotation can be used almost everywhere.
solid answer
~40 s@Target is a meta-annotation that limits where a custom annotation may legally appear. You give it one or more ElementType constants — e.g. TYPE (classes/interfaces), METHOD, FIELD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, plus TYPE_PARAMETER and TYPE_USE added in Java 8. The compiler then rejects any use on an element not in that list, giving you a compile-time error instead of a misplaced annotation. If you omit @Target entirely, there is no restriction: the annotation is applicable in all the contexts that allow annotations (it is not magically blocked from anything). So @Target is about authoring safety — it constrains the surface area of your annotation so consumers cannot misuse it.
go deeper
Knows @Target limits where an annotation can be placed and that values come from ElementType.
Lists the common ElementType values and knows omitting @Target means 'applicable everywhere', with enforcement at compile time.
Designs annotations with the narrowest correct @Target and understands TYPE vs TYPE_USE and the empty-array meta-only case.
Leverages TYPE_USE for pluggable type-checking frameworks and sets annotation-surface conventions across an API to prevent misuse.
## Background An **annotation** is an `@`-marker attached to code. A **meta-annotation** is an annotation placed on the declaration of *another* annotation to configure it. `@Target` is the meta-annotation that controls **where** your annotation is allowed to be written. ## ElementType — the menu of locations `@Target` takes an array of `java.lang.annotation.ElementType` enum constants. Each names a kind of program element: - `TYPE` — a class, interface, enum, or annotation type. - `FIELD` — a field (including enum constants). - `METHOD` — a method. - `PARAMETER` — a method/constructor parameter. - `CONSTRUCTOR` — a constructor. - `LOCAL_VARIABLE` — a local variable. - `ANNOTATION_TYPE` — only on another annotation declaration (this is how you mark something as a meta-annotation). - `PACKAGE` — a package (in `package-info.java`). - `TYPE_PARAMETER` (Java 8) — a generic type parameter, e.g. `<@NonNull T>`. - `TYPE_USE` (Java 8) — *any use of a type*, enabling type annotations like `List<@NonNull String>` or `@NonNull String name`. ## What omitting @Target means If you do **not** put `@Target` on your annotation, there is **no restriction** — it may be applied in every declaration context where annotations are permitted. A common misconception is that no `@Target` means 'nowhere' or 'only types'; it actually means 'everywhere (that annotations are legal)'. So @Target is opt-in *tightening*. ## Why use it The benefit is **compile-time enforcement**. If `@Column` is meant for fields only, `@Target(ElementType.FIELD)` makes the compiler reject `@Column` on a method with a clear error, instead of letting the mistake compile and surface later (or never) at runtime. It documents intent and prevents misuse. ## Multiple targets You can allow several: `@Target({ElementType.METHOD, ElementType.FIELD})`. An empty array `@Target({})` is a special, legal case meaning the annotation can only be used as a meta-annotation on *other* annotations and nowhere else — it is even more restrictive than naming ANNOTATION_TYPE in some respects. ## Type annotations (Java 8) `TYPE_USE` and `TYPE_PARAMETER` were introduced in Java 8 to support **type annotations** — annotations on the *use* of a type rather than on a declaration. This powers pluggable type checkers (e.g. nullness checkers): `@NonNull String` annotates the type `String` wherever it appears, not the variable declaration as a whole. ## Example ```java import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @interface Sensitive {} class Account { @Sensitive String password; // OK (FIELD) @Sensitive void wipe() {} // OK (METHOD) // @Sensitive class X {} // COMPILE ERROR — TYPE not in @Target } ```
- What is the difference between ElementType.TYPE and ElementType.TYPE_USE?TYPE restricts the annotation to declarations of a class/interface/enum/annotation. TYPE_USE (Java 8) allows it on any *use* of a type — generic arguments, casts, throws, etc. — enabling type annotations like List<@NonNull String>.
saying these in an interview costs you the question
- Saying that omitting @Target blocks the annotation everywhere or limits it to types.
- Confusing @Target (where it can go) with @Retention (how long it lives).
- Believing @Target enforcement is a runtime check — it is enforced by the compiler.
- Thinking TYPE covers TYPE_USE contexts like generic type arguments.