Java Annotations Advanced
In this page:
Creating Custom Annotations
Custom annotations let you attach structural metadata tags to your code that tools, compilers, or runtime frameworks can later read and act on, without that metadata changing the actual runtime behavior of the annotated code by itself.
Example: Creating Custom Annotations
import java.lang.annotation.*;
public class Main {
@interface Info { String value(); } // structural metadata, no runtime behavior on its own
@Info("demo")
static class Sample {}
public static void main(String[] args) {
System.out.println("Custom annotation @Info declared");
}
}
Login to try C/C++/Java/PHP code in the editor
Retention Policy levels
The @Retention policy controls how long an annotation's metadata survives: SOURCE annotations are stripped by the compiler and never make it into the .class file, while RUNTIME annotations are preserved so they can be read via reflection while the program is executing.
Example: Retention Policy levels
import java.lang.annotation.*;
public class Main {
@Retention(RetentionPolicy.RUNTIME) // preserved so reflection can read it while running
@interface Tag { String value(); }
@Tag("example")
static class Sample {}
public static void main(String[] args) {
Tag tag = Sample.class.getAnnotation(Tag.class);
System.out.println(tag.value());
}
}
Login to try C/C++/Java/PHP code in the editor
Targeting Annotation Elements
The @Target annotation restricts where a custom annotation is allowed to be placed -- for example, limiting it to fields only, or methods only -- so the compiler can catch misuse (like applying a field-only annotation to a class) instead of silently allowing it.
Example: Targeting Annotation Elements
import java.lang.annotation.*;
public class Main {
@Target(ElementType.FIELD) // restricted to fields only
@Retention(RetentionPolicy.RUNTIME)
@interface Required {}
static class Sample {
@Required
String name;
}
public static void main(String[] args) {
System.out.println("@Required can only be placed on fields");
}
}
Login to try C/C++/Java/PHP code in the editor
Annotation Inheritance
Annotations are not automatically inherited by subclasses the way fields and methods are, unless the annotation's own declaration is itself marked @Inherited. This surprises a lot of developers who assume annotation behavior mirrors regular Java inheritance.
Example: Annotation Inheritance
import java.lang.annotation.*;
public class Main {
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Marker {}
@Marker
static class Parent {}
static class Child extends Parent {}
public static void main(String[] args) {
System.out.println(Child.class.isAnnotationPresent(Marker.class)); // true, because @Inherited was used
}
}
Login to try C/C++/Java/PHP code in the editor
Annotation Processing
At runtime, annotation processors use reflection to scan for annotated elements and act on them -- validating object state, mapping fields to database columns, or registering routes -- which is the mechanism that lets frameworks like JPA and Spring translate your annotations into real behavior.
Example: Annotation Processing
import java.lang.annotation.*;
import java.lang.reflect.*;
public class Main {
@Retention(RetentionPolicy.RUNTIME)
@interface Column { String name(); }
static class User {
@Column(name = "user_name")
String name;
}
public static void main(String[] args) throws Exception {
Field field = User.class.getDeclaredField("name");
Column column = field.getAnnotation(Column.class);
System.out.println("Maps to DB column: " + column.name()); // annotation processor scanning at runtime
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 19 topics to unlock
0/19 topics done
Complete these topics first:
- Java Reflection API
- Java Annotations Advanced
- Java Garbage Collection
- Java Memory Management
- Java Performance Optimization
- Java Advanced Interview Questions
- Java CompletableFuture
- Java Atomic Classes
- Java Locks & Semaphores
- Java Concurrent Collections
- Java Cryptography Basics
- Java Hashing (MD5, SHA)
- Java SSL & HTTPS
- Java Logging (Log4j/SLF4J)
- Java Serialization Advanced
- Java Interview Questions Advanced
- Java Connection Pooling
- Java Test Driven Development
- Java Integration Testing