Java Annotations: Complete Guide
Annotations in Java are metadata that provide additional information about code. They do not directly affect program logic but can be used by the compiler or runtime to influence behavior.
What is an Annotation?
An annotation is defined using @ symbol. It is used to mark classes, methods, fields, or parameters.
@Override
public String toString() {
return "Hello";
}- Provides metadata
- Used by compiler or runtime
- Helps frameworks process code
- Improves readability and maintainability
Built-in Annotations
- @Override → Ensures method overriding
- @Deprecated → Marks outdated code
- @SuppressWarnings → Suppresses compiler warnings
- @FunctionalInterface → Ensures single abstract method
Meta-Annotations
Meta-annotations define how custom annotations behave.
- @Target → Where annotation can be applied
- @Retention → How long annotation is available
- @Documented → Include in Javadoc
- @Inherited → Allow inheritance
Retention Policies
- SOURCE → Available only in source code
- CLASS → Stored in .class file (default)
- RUNTIME → Available at runtime (used with reflection)
Creating Custom Annotation
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
String value();
int count() default 1;
}Using Custom Annotation
class Test {
@MyAnnotation(value = "Hello", count = 2)
public void sayHello() {
System.out.println("Hello Method");
}
}Accessing Annotation Using Reflection
import java.lang.reflect.Method;
class Main {
public static void main(String[] args) throws Exception {
Method m = Test.class.getMethod("sayHello");
if (m.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation ann = m.getAnnotation(MyAnnotation.class);
System.out.println(ann.value());
System.out.println(ann.count());
}
}
}Complex Example: Real Use Case
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface LogExecution {
}
class Service {
@LogExecution
public void process() {
System.out.println("Processing...");
}
}
public class Main {
public static void main(String[] args) throws Exception {
Service service = new Service();
for (Method m : service.getClass().getDeclaredMethods()) {
if (m.isAnnotationPresent(LogExecution.class)) {
System.out.println("Method " + m.getName() + " is annotated");
m.invoke(service);
}
}
}
}Output
Method process is annotated
Processing...Why Annotations are Used
- Configuration without XML (Spring)
- Code generation tools
- Validation frameworks
- Dependency Injection
- Aspect-Oriented Programming
Disadvantages
- Overuse makes code complex
- Hidden logic
- Requires reflection (performance cost)
- Harder debugging
Best Practices
- Use meaningful annotation names
- Avoid too many custom annotations
- Use RUNTIME only when needed
- Document annotation usage
- Keep annotations simple
Interview Tips
- Annotations are metadata, not logic
- RetentionPolicy.RUNTIME is needed for reflection
- @Target defines usage scope
- Used heavily in Spring Boot
- Custom annotations are common interview topic
Final Summary
- Annotations provide metadata
- Can be built-in or custom
- Controlled using meta-annotations
- Used with reflection for dynamic behavior
- Widely used in modern frameworks