Java Tutorial 0/145 lessons ~6 min read Lesson 37

    Java Annotations

    java annotations @Override @Deprecated @Target @Retention custom annotation Spring Hibernate JUnit metadata

    Course progress0%
    Focus
    32 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    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:

    code
    @Service
    public 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:

    code
    @Override
    public 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.

    code
    <bean id="employeeService"
    class="EmployeeService"/>

    Today:

    code
    @Service
    public class EmployeeService {
    }

    Benefits:

    • Less configuration
    • Cleaner code
    • Better maintainability
    • Compile-time validation
    • Framework automation

    Annotation Syntax

    General form:

    code
    @AnnotationName

    Example:

    code
    @Deprecated

    Types of Annotations

    Java annotations can be categorized as:

    • Marker Annotations
    • Single Value Annotations
    • Full Annotations

    Marker Annotation

    Contains no elements.

    Example:

    code
    @Override
    @Test
    @Deprecated

    Usage:

    code
    @Override
    public void display(){
    }

    Single Value Annotation

    Contains one element.

    Example:

    code
    @Author("Jagannath")

    Equivalent to:

    code
    @Author(value = "Jagannath")

    Full Annotation

    Contains multiple elements.

    code
    @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.

    code
    class Animal{
    void sound(){}
    }
    class Dog extends Animal{
    @Override
    void sound(){
    System.out.println("Bark");
    }
    }

    Benefits:

    • Compiler validation
    • Prevents spelling mistakes

    @Deprecated

    Marks APIs that should no longer be used.

    code
    @Deprecated
    public void oldMethod(){
    }

    Calling:

    code
    oldMethod();

    Produces a compiler warning.

    @SuppressWarnings

    Suppresses compiler warnings.

    code
    @SuppressWarnings("unchecked")
    List list =
    new ArrayList();

    Use it only when the warning is understood and unavoidable.

    @FunctionalInterface

    Marks an interface as a Functional Interface.

    code
    @FunctionalInterface
    interface 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.

    code
    @Target(ElementType.METHOD)

    Common targets:

    • TYPE
    • METHOD
    • FIELD
    • PARAMETER
    • CONSTRUCTOR
    • LOCAL_VARIABLE

    @Retention

    Defines how long an annotation is retained.

    code
    @Retention(RetentionPolicy.RUNTIME)

    Policies:

    PolicyDescription
    SOURCEDiscarded after compilation
    CLASSStored in class file but unavailable at runtime
    RUNTIMEAvailable through Reflection

    @Inherited

    Allows child classes to inherit class-level annotations.

    code
    @Inherited

    @Documented

    Includes annotations in generated API documentation.

    code
    @Documented

    @Repeatable

    Allows multiple instances of the same annotation.

    code
    @Repeatable(Roles.class)

    Example:

    code
    @Role("ADMIN")
    @Role("USER")

    Creating a Custom Annotation

    code
    import java.lang.annotation.*;
    @Retention(
    RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Author{
    String value();
    }

    Using it:

    code
    @Author("Jagannath")
    class Course{
    }

    Annotation with Multiple Elements

    code
    @Retention(
    RetentionPolicy.RUNTIME)
    @interface Employee{
    String name();
    int age();
    }

    Using:

    code
    @Employee(
    name="Rahul",
    age=30
    )
    class Developer{
    }

    Reading Annotations using Reflection

    code
    Author author =
    Course.class.getAnnotation(
    Author.class);
    System.out.println(
    author.value());

    Output:

    code
    Jagannath

    Spring Boot Annotations

    Common annotations:

    code
    @SpringBootApplication
    @RestController
    @Service
    @Repository
    @Component
    @Autowired
    @RequestMapping

    Spring scans these annotations using Reflection to create beans and configure the application.

    Hibernate Annotations

    Examples:

    code
    @Entity
    @Table
    @Id
    @Column
    @GeneratedValue

    Hibernate uses these annotations to map Java classes to database tables.

    JUnit Annotations

    Examples:

    code
    @Test
    @BeforeEach
    @AfterEach
    @BeforeAll
    @AfterAll

    JUnit discovers test methods through Reflection.

    Annotation Processing Flow

    code
    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:

    code
    @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:

    1. Uses @Override.
    2. Uses @Deprecated.
    3. Uses @FunctionalInterface.
    4. Creates a custom @Author annotation.
    5. Creates a custom @EmployeeInfo annotation with multiple elements.
    6. Applies @Target and @Retention.
    7. Reads custom annotations using Reflection.
    8. Creates a repeatable annotation.
    9. Demonstrates @Inherited.
    10. 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.

    Ready to mark this lesson complete?Track your journey across the entire course.