Annotations in Java provide a powerful way to add metadata to your code, enabling cleaner syntax, reducing boilerplate, and powering frameworks like Spring, Hibernate, and JAX-RS. They are a key component in modern Java development.
1. What Are Annotations?
Annotations are metadata added to Java code that can be read and processed at compile-time, class-load time, or runtime using reflection.
They do not directly affect program logic, but they inform tools, frameworks, or the compiler about how the code should be treated.
2. Common Built-In Annotations
@Override
: Ensures a method overrides a superclass method.@Deprecated
: Marks a method/class as outdated.@SuppressWarnings
: Instructs the compiler to ignore specific warnings.@FunctionalInterface
: Indicates an interface with one abstract method.
3. Meta-Annotations (Annotations for Annotations)
@Target
: Specifies where the annotation can be applied (e.g., method, field).@Retention
: Specifies whether the annotation is available at source, class, or runtime.@Inherited
: Allows subclasses to inherit the annotation.@Documented
: Includes annotation in Javadoc.
Example:
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
4. Creating Custom Annotations
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
String table() default "";
}
Apply it:
java
@Entity(table = "users")
public class User { }
5. Accessing Annotations with Reflection
You can read annotations at runtime using reflection:
java
Entity entity = User.class.getAnnotation(Entity.class);
System.out.println(entity.table()); // prints "users"
6. Annotations in Frameworks
Spring Framework:
@Autowired
, @Service
, @RestController
, @RequestMapping
- Drive dependency injection and web routing.
Hibernate (JPA):
@Entity
, @Id
, @Column
- Map classes to database tables.
JUnit:
@Test
, @BeforeEach
, @AfterAll
7. Retention Policies
SOURCE
: Discarded after compilation.CLASS
: Present in .class
file, not at runtime.RUNTIME
: Retained and accessible at runtime via reflection.
Choose the right policy based on your use case. Frameworks usually require RUNTIME
.
8. Best Practices
- Keep annotations descriptive and minimal.
- Use default values to make usage flexible.
- Document custom annotations clearly.
- Use meta-annotations appropriately for better control.
Java annotations offer a clean and declarative way to attach behavior and meaning to code, playing a pivotal role in modern Java frameworks and APIs. By mastering annotations, developers can unlock cleaner code and more powerful abstractions.