Java Annotations
java annotations @Override @Deprecated @Target @Retention custom annotation Spring Hibernate JUnit metadata
Introduction
In the previous lesson, you learned about the Java Reflection API, which enables programs to inspect classes, methods, constructors, fields, and annotations at runtime.
However, have you ever wondered how frameworks like Spring Boot, Hibernate, and JUnit know:
- Which class is a Service?
- Which class is an Entity?
- Which method is a Test?
- Which field should be injected?
- Which URL should invoke a controller method?
For example:
@Servicepublic class EmployeeService {}
How does Spring know that this is a Service?
The answer is Annotations.
Annotations provide metadata about Java code.
They do not directly change program execution but provide information that the compiler, JVM, or frameworks can use.
Annotations are heavily used in:
- Spring Boot
- Spring MVC
- Spring Security
- Hibernate / JPA
- JUnit
- Jackson
- Lombok
- Jakarta EE
- Android Development
Mastering annotations is essential for enterprise Java development.
In this lesson, you'll learn:
- What are Annotations?
- Why Annotations?
- Built-in Annotations
- Marker Annotations
- Single Value Annotations
- Full Annotations
- Meta-Annotations
- Custom Annotations
- Annotation Retention Policies
- Annotation Targets
- Repeatable Annotations
- Reflection with Annotations
- Spring & Hibernate Internals
- Best Practices
- Common Mistakes
- Hands-on Exercises
- Professional Interview Questions
What is an Annotation?
An Annotation is metadata that provides additional information about a program.
Example:
@Overridepublic String toString(){return "Employee";}
The annotation tells the compiler:
This method overrides a superclass method.
Annotations:
- Improve readability
- Reduce configuration
- Enable framework automation
- Support compile-time checking
Why Annotations?
Before annotations, XML configuration was common.
<bean id="employeeService"class="EmployeeService"/>
Today:
@Servicepublic class EmployeeService {}
Benefits:
- Less configuration
- Cleaner code
- Better maintainability
- Compile-time validation
- Framework automation
Annotation Syntax
General form:
@AnnotationName
Example:
@Deprecated
Types of Annotations
Java annotations can be categorized as:
- Marker Annotations
- Single Value Annotations
- Full Annotations
Marker Annotation
Contains no elements.
Example:
@Override@Test@Deprecated
Usage:
@Overridepublic void display(){}
Single Value Annotation
Contains one element.
Example:
@Author("Jagannath")
Equivalent to:
@Author(value = "Jagannath")
Full Annotation
Contains multiple elements.
@Employee(name="Rahul",age=30,department="IT")
Built-in Annotations
Java provides several built-in annotations.
Most commonly used:
- @Override
- @Deprecated
- @SuppressWarnings
- @FunctionalInterface
- @SafeVarargs
- @Native
@Override
Ensures a method correctly overrides a superclass method.
class Animal{void sound(){}}class Dog extends Animal{@Overridevoid sound(){System.out.println("Bark");}}
Benefits:
- Compiler validation
- Prevents spelling mistakes
@Deprecated
Marks APIs that should no longer be used.
@Deprecatedpublic void oldMethod(){}
Calling:
oldMethod();
Produces a compiler warning.
@SuppressWarnings
Suppresses compiler warnings.
@SuppressWarnings("unchecked")List list =new ArrayList();
Use it only when the warning is understood and unavoidable.
@FunctionalInterface
Marks an interface as a Functional Interface.
@FunctionalInterfaceinterface Calculator{int add(int a,int b);}
Adding another abstract method causes a compilation error.
Meta-Annotations
Meta-annotations are annotations applied to annotation definitions.
Common meta-annotations:
- @Target
- @Retention
- @Inherited
- @Documented
- @Repeatable
@Target
Specifies where an annotation can be applied.
@Target(ElementType.METHOD)
Common targets:
- TYPE
- METHOD
- FIELD
- PARAMETER
- CONSTRUCTOR
- LOCAL_VARIABLE
@Retention
Defines how long an annotation is retained.
@Retention(RetentionPolicy.RUNTIME)
Policies:
| Policy | Description |
|---|---|
| SOURCE | Discarded after compilation |
| CLASS | Stored in class file but unavailable at runtime |
| RUNTIME | Available through Reflection |
@Inherited
Allows child classes to inherit class-level annotations.
@Inherited
@Documented
Includes annotations in generated API documentation.
@Documented
@Repeatable
Allows multiple instances of the same annotation.
@Repeatable(Roles.class)
Example:
@Role("ADMIN")@Role("USER")
Creating a Custom Annotation
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface Author{String value();}
Using it:
@Author("Jagannath")class Course{}
Annotation with Multiple Elements
@Retention(RetentionPolicy.RUNTIME)@interface Employee{String name();int age();}
Using:
@Employee(name="Rahul",age=30)class Developer{}
Reading Annotations using Reflection
Author author =Course.class.getAnnotation(Author.class);System.out.println(author.value());
Output:
Jagannath
Spring Boot Annotations
Common annotations:
@SpringBootApplication@RestController@Service@Repository@Component@Autowired@RequestMapping
Spring scans these annotations using Reflection to create beans and configure the application.
Hibernate Annotations
Examples:
@Entity@Table@Id@Column@GeneratedValue
Hibernate uses these annotations to map Java classes to database tables.
JUnit Annotations
Examples:
@Test@BeforeEach@AfterEach@BeforeAll@AfterAll
JUnit discovers test methods through Reflection.
Annotation Processing Flow
Annotation↓Compiler / JVM↓Reflection↓Framework↓Application Behavior
Best Practices
Use Standard Annotations
Prefer built-in annotations whenever possible.
Keep Custom Annotations Focused
Each annotation should represent one clear purpose.
Choose the Correct Retention Policy
Use RUNTIME only when runtime processing is required.
Avoid Excessive Annotation Usage
Too many annotations can reduce readability.
Document Custom Annotations
Clearly describe the purpose and usage of custom annotations.
Common Mistakes
Forgetting Runtime Retention
Without:
@Retention(RetentionPolicy.RUNTIME)
Reflection cannot access the annotation.
Wrong Target
Using an annotation on an unsupported element causes a compilation error.
Overusing @SuppressWarnings
Suppress only well-understood warnings.
Confusing Annotations with Business Logic
Annotations provide metadata; the actual behavior comes from the compiler, JVM, or frameworks.
Creating Unnecessary Custom Annotations
Reuse existing annotations whenever they meet the requirement.
Hands-on Exercise
Create a Java program that:
- Uses @Override.
- Uses @Deprecated.
- Uses @FunctionalInterface.
- Creates a custom @Author annotation.
- Creates a custom @EmployeeInfo annotation with multiple elements.
- Applies @Target and @Retention.
- Reads custom annotations using Reflection.
- Creates a repeatable annotation.
- Demonstrates @Inherited.
- Builds a simple annotation scanner.
Summary
Java Annotations provide metadata that helps the compiler, JVM, and frameworks understand how classes, methods, and fields should be processed. They replace much of the XML configuration previously required in enterprise applications. Modern frameworks such as Spring Boot, Hibernate, Jackson, and JUnit rely extensively on annotations combined with Reflection to deliver dependency injection, object-relational mapping, serialization, testing, and many other features.
Key Takeaways
- Annotations provide metadata.
- They do not directly change business logic.
- Built-in annotations improve safety and readability.
- Meta-annotations define annotation behavior.
- @Retention controls annotation lifetime.
- @Target defines where annotations may be applied.
- Custom annotations support application-specific metadata.
- Reflection is used to read runtime annotations.
- Spring and Hibernate rely heavily on annotations.
- Annotations reduce configuration and improve maintainability.
Professional Interview Questions
1What are Annotations in Java?
Professional Answer
Annotations are a form of metadata that provide additional information about classes, methods, fields, parameters, and other program elements. They do not directly alter program logic but are interpreted by the compiler, JVM, or frameworks such as Spring and Hibernate to enable features like dependency injection, object mapping, and validation.
Follow-up Questions
- Can annotations contain methods?
- Which retention policy is required for Reflection?
Interview Tip: Remember: Annotation = Metadata, not Business Logic.
2What is the difference between @Target and @Retention?
Professional Answer
@Target specifies where an annotation can be applied, such as a class, method, field, or parameter. @Retention specifies how long the annotation should be retained, whether only in source code, in the compiled class file, or available at runtime through Reflection.
Follow-up Questions
- Which retention policy allows runtime access?
- Can an annotation target multiple element types?
Interview Tip: @Target → Where, @Retention → How Long.
3How do Spring Boot and Hibernate use Annotations?
Professional Answer
Spring Boot uses annotations such as @Component, @Service, @Repository, and @Autowired to discover beans, configure dependency injection, and manage the application context. Hibernate uses annotations like @Entity, @Table, @Id, and @Column to map Java classes and fields to database tables and columns. Both frameworks use Reflection to scan and process these annotations at runtime.
Follow-up Questions
- Which Spring annotation marks a service class?
- Which Hibernate annotation identifies an entity?
Interview Tip: Spring → Dependency Injection, Hibernate → Database Mapping, Reflection → Reads the Annotations.