Annotations in Java are metadata added to code. They do not directly affect program logic, but provide information to:
- Compiler
- JVM
- Frameworks (Spring, Hibernate, JPA)
- Build tools (Maven, Gradle)
Annotations are written using @.
Example:
@Override
public String toString() { ... }-
Provide metadata e.g.,
@Deprecated,@SuppressWarnings -
Compiler instructions e.g.,
@Override,@FunctionalInterface -
Runtime processing with Reflection Used by Spring, JPA, Hibernate, Jackson
-
Code generation Lombok (
@Getter,@Setter) -
Validation e.g., Jakarta Validation (
@NotNull,@Min)
Ensures that a method overrides a parent method.
@Override
void run() { }If method signature doesn't match parent method → compiler error.
Marks API as outdated.
@Deprecated
void oldMethod() { }Warnings appear if used.
Suppress compiler warnings.
@SuppressWarnings("unchecked")
void test() { }Ensures interface has exactly one abstract method.
@FunctionalInterface
interface Operation {
int apply(int x, int y);
}Suppresses unchecked warnings for varargs of generics.
@SafeVarargs
static <T> void print(T... items) { }Specifies how long annotation is retained.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno { }Types:
| Retention Policy | Meaning |
|---|---|
SOURCE |
Removed during compilation |
CLASS |
Stored in .class file (default) |
RUNTIME |
Available during runtime (reflection) |
Specifies where annotation can be applied.
@Target(ElementType.METHOD)
@interface MyAnno { }Targets include:
- TYPE
- METHOD
- FIELD
- PARAMETER
- CONSTRUCTOR
- LOCAL_VARIABLE
- PACKAGE
Marks that an annotation should appear in Javadoc.
Child classes inherit the annotation.
You can create your own annotations using @interface.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface RunTest {
int times() default 1;
}Usage:
class Demo {
@RunTest(times = 3)
void test() { }
}Example of reading annotation at runtime:
Method[] methods = Demo.class.getDeclaredMethods();
for (Method m : methods) {
if (m.isAnnotationPresent(RunTest.class)) {
RunTest rt = m.getAnnotation(RunTest.class);
System.out.println("Run " + m.getName() + " " + rt.times() + " times");
}
}| Annotation | Purpose |
|---|---|
@Retention |
Specifies how long annotation stays |
@Target |
Where annotation can be applied |
@Documented |
Included in Javadoc |
@Inherited |
Inherited by subclasses |
@Repeatable |
Same annotation can be applied multiple times |
Example of repeatable:
@Repeatable(Tags.class)
@interface Tag {
String name();
}
@interface Tags {
Tag[] value();
}@Component
@Service
@RestController
@Autowired
@RequestMapping("/api")Used for dependency injection and component scanning.
@Entity
@Id
@GeneratedValue
@Column(name = "user_id")Used for ORM mapping.
| Annotation | Retention | Example |
|---|---|---|
| Compile-time | SOURCE / CLASS |
@Override, @Deprecated |
| Runtime | RUNTIME |
@Entity, @Autowired |
Frameworks require annotations available at runtime.
Metadata that provides information to compiler/JVM/tools.
@Overridechecks method overriding.@FunctionalInterfaceensures single abstract method.
Specifies how long annotation is kept (source, class, runtime).
Yes—called annotation elements.
Yes.
int value() default 10;No. But they can use @Repeatable and @Inherited.
-
Annotations add metadata to code.
-
They influence compilers, tools, and frameworks.
-
Built-in annotations:
@Override,@Deprecated,@SuppressWarnings. -
Meta-annotations:
@Retention,@Target,@Inherited. -
Custom annotations are created with
@interface. -
Widely used in Spring, JPA, Jackson, and Lombok.