CodeToConcept
About

java

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

java Tutorials

Introduction
Java Variables
Java Data Types
Java Type Casting
Java Operators
Java Input/Output
Java Class & Object
java Method
Java Constructor
Java this keyword
Java super keyword
Java Method Overloading and Overriding
Java Interface
Java Abstract Class
Java Memory Management
Design Patterns
JDBC (Database Connectivity)
Java IDEs

Sample Question

Think it through, then check the tutorial.

CodeToConcept

Quickly learn through simple, structured, and practical coding tutorials. Build your confidence from step zero to real-world experience.

© 2026 CodeToConcept. All rights reserved.

Quick Links

AboutTutorials

Tutorials

JavaHTMLCSS

Support

Privacy PolicyTerms of ServiceContact
GitHubTwitterYouTube

Java Annotations

Run each complete program separately. Its required helper classes and imports are included in the same code block. Short syntax fragments explain individual operations.

An annotation adds metadata to a Java declaration or type use. A compiler, processor, framework, or runtime tool decides what that metadata means. Writing an annotation does not automatically run application logic.

Annotations are widely used in modern Java development and frameworks such as Spring, JUnit, Hibernate, and many other libraries.

For example:

@Override
public String toString() {
    return "Hello";
}

Here, @Override is an annotation. It tells the compiler that the method is intended to override a method from its parent class.

What is an Annotation in Java?

An annotation is a special form of metadata that starts with the @ symbol.

Syntax

@AnnotationName

Example

@Override

Annotations can also contain values:

@SuppressWarnings("unchecked")

Or multiple values:

@Example(name = "Java", version = 21)

Simple Definition

An annotation provides additional information about program elements such as classes, methods, fields, constructors, and parameters.

Annotations themselves generally do not directly execute business logic. Instead, the compiler, JVM, development tools, or frameworks can use the information provided by annotations.

Why Are Annotations Used?

Annotations are commonly used for:

  • Providing information to the compiler
  • Generating compiler warnings
  • Marking deprecated code
  • Configuring frameworks
  • Runtime processing
  • Testing
  • Dependency injection
  • Mapping objects to database tables
  • Defining configuration
  • Code generation

For example, Spring uses annotations such as:

@Component
@Service
@Repository
@Autowired

JUnit uses annotations such as:

@Test
@BeforeEach
@AfterEach

Basic Example

Consider:

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

Here:

@Override

is an annotation.

It tells the compiler:

This method is intended to override a method from the superclass.

Output

Dog barks

Types of Annotations

Java annotations can broadly be classified into:

  1. Predefined annotations
  2. Meta-annotations
  3. Custom annotations

1. Predefined Annotations

Java provides several built-in annotations.

Some commonly used ones are:

AnnotationPurpose
@OverrideIndicates method overriding
@DeprecatedMarks an element as deprecated
@SuppressWarningsSuppresses compiler warnings
@FunctionalInterfaceIndicates a functional interface
@SafeVarargsSuppresses certain varargs warnings
@RepeatableAllows an annotation to be repeated

@Override

@Override indicates that a method is intended to override a method from a superclass or implement a method from an interface.

Example

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

Why use @Override?

It helps the compiler detect mistakes.

For example:

class Dog extends Animal {
 
    @Override
    void sounds() {
        System.out.println("Dog barks");
    }
}

If sounds() does not actually override a parent method, the compiler reports an error.

Without @Override, such a typo could accidentally create a new method.

@Deprecated

@Deprecated marks a class, method, field, or other program element as no longer recommended for use.

Example

class Calculator {
 
    @Deprecated
    public void oldMethod() {
        System.out.println("Old method");
    }
 
    public void newMethod() {
        System.out.println("New method");
    }
}

Using:

Calculator calculator = new Calculator();
 
calculator.oldMethod();

can cause a compiler or IDE warning indicating that the method is deprecated.

Deprecated for Removal

Modern Java also supports:

@Deprecated(forRemoval = true)

This communicates that the API is intended to be removed in a future release.

@SuppressWarnings

@SuppressWarnings tells the compiler to suppress specific warnings.

Example

import java.util.ArrayList;
import java.util.List;
 
class Demo {
 
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
 
        List list = new ArrayList();
 
        list.add("Java");
 
        String value = (String) list.get(0);
 
        System.out.println(value);
    }
}

Output

Java

The annotation does not fix the underlying issue. It only tells the compiler not to report the specified warning.

Therefore, it should be used carefully.

@FunctionalInterface

@FunctionalInterface indicates that an interface is intended to contain exactly one abstract method.

Example

@FunctionalInterface
interface Calculator {
 
    int calculate(int a, int b);
}

This can be used with a lambda expression:

@FunctionalInterface
interface Calculator {
 
    int calculate(int a, int b);
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Calculator calculator = (a, b) -> a + b;
 
        System.out.println(calculator.calculate(10, 20));
    }
}

Output

30

If another abstract method is added:

@FunctionalInterface
interface Calculator {
 
    int calculate(int a, int b);
 
    int multiply(int a, int b);
}

the compiler reports an error because the interface is no longer a functional interface.

2. Meta-Annotations

Meta-annotations are annotations used to define or configure other annotations.

Some important meta-annotations are:

  • @Target
  • @Retention
  • @Documented
  • @Inherited
  • @Repeatable

@Target

@Target specifies where an annotation can be applied.

For example:

@Target(ElementType.METHOD)
@interface MyAnnotation {
}

This means @MyAnnotation can only be used on methods.

Example

class Demo {
 
    @MyAnnotation
    void show() {
        System.out.println("Hello");
    }
}

The annotation cannot be applied to a class if its target is restricted to methods.

ElementType

ElementType defines the program elements where an annotation can be used.

Common values include:

ElementTypeUsed On
TYPEClass, interface, enum, annotation
FIELDField
METHODMethod
PARAMETERMethod parameter
CONSTRUCTORConstructor
LOCAL_VARIABLELocal variable
ANNOTATION_TYPEAnnotation declaration
PACKAGEPackage
TYPE_PARAMETERType parameter
TYPE_USEType usage

Example

@Target({
    ElementType.TYPE,
    ElementType.METHOD
})
@interface Info {
}

Now the annotation can be applied to both classes and methods.

@Retention

@Retention defines how long an annotation should be available.

There are three retention policies:

RetentionPolicy.SOURCE
RetentionPolicy.CLASS
RetentionPolicy.RUNTIME

SOURCE

The annotation is available only in the source code.

It is discarded by the compiler and is not available in the compiled .class file.

Example

@Retention(RetentionPolicy.SOURCE)
@interface MyAnnotation {
}

This type of annotation can be useful for source-code tools.

CLASS

The annotation is stored in the compiled .class file but is generally not available through normal runtime reflection.

Example

@Retention(RetentionPolicy.CLASS)
@interface MyAnnotation {
}

CLASS is the default retention policy if no @Retention is specified.

RUNTIME

The annotation is retained at runtime and can be accessed through reflection.

Example

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
}

Runtime annotations are especially important for frameworks.

For example, a framework can inspect a class and check whether a particular annotation is present.

Retention Policy Comparison

PolicySource Code.class FileRuntime Reflection
SOURCEYesNoNo
CLASSYesYesGenerally no
RUNTIMEYesYesYes

Creating a Custom Annotation

Java allows developers to create their own annotations.

The basic syntax is:

@interface AnnotationName {
}

Example

@interface MyAnnotation {
}

Usage:

@MyAnnotation
class Student {
 
}

Custom Annotation with @Target and @Retention

A more useful custom annotation can be defined like this:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Info {
}

Now:

@Info
class Student {
 
}

The annotation can be detected at runtime.

Annotation with a Value

An annotation can contain elements.

Example

@interface Author {
 
    String name();
}

Usage:

@Author(name = "John")
class Student {
 
}

Here:

name()

is an annotation element.

Annotation Elements with Default Values

Annotation elements can have default values.

Example

@interface StudentInfo {
 
    String name();
 
    int age() default 18;
}

Now we can write:

@StudentInfo(name = "John")
class Student {
 
}

The value of age will be:

18

We can also explicitly provide it:

@StudentInfo(name = "John", age = 20)
class Student {
 
}

Annotation Element Rules

Annotation elements have restrictions on their types.

They can commonly use:

  • Primitive types
  • String
  • Class
  • Enum
  • Annotation types
  • Arrays of supported annotation element types

Example

@interface EmployeeInfo {
 
    String name();
 
    int age();
 
    Class<?> type();
 
    String[] skills();
}

Usage:

@EmployeeInfo(
    name = "John",
    age = 25,
    type = String.class,
    skills = {"Java", "Spring"}
)
class Employee {
 
}

Single-Value Annotation

If an annotation has a single element named value, the element name can be omitted.

Example

@interface Author {
 
    String value();
}

Instead of:

@Author(value = "John")

we can write:

@Author("John")

This is a common annotation pattern.

Reading Annotations Using Reflection

Annotations become particularly useful when they can be inspected at runtime.

Consider:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 
@Retention(RetentionPolicy.RUNTIME)
@interface Author {
 
    String name();
}

Apply it to a class:

@Author(name = "John")
class Student {
 
}

Now we can read the annotation using reflection.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface Author {
 
    String name();
}
 
@Author(name = "John")
class Student {
 
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Class<Student> clazz = Student.class;
 
        Author author = clazz.getAnnotation(Author.class);
 
        System.out.println(author.name());
    }
}

Output

John

Complete Custom Annotation Example

Let's create a custom annotation that stores information about an employee.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface EmployeeInfo {
 
    String name();
 
    String department();
 
    int experience();
}
 
@EmployeeInfo(
    name = "John",
    department = "Development",
    experience = 5
)
class Employee {
 
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Class<Employee> clazz = Employee.class;
 
        EmployeeInfo info =
                clazz.getAnnotation(EmployeeInfo.class);
 
        System.out.println("Name: " + info.name());
        System.out.println("Department: " + info.department());
        System.out.println("Experience: " + info.experience());
    }
}

Output

Name: John
Department: Development
Experience: 5

How it works

The annotation:

@EmployeeInfo(...)

stores metadata on the Employee class.

Because we used:

@Retention(RetentionPolicy.RUNTIME)

the metadata remains available at runtime.

Then:

clazz.getAnnotation(EmployeeInfo.class)

retrieves the annotation.

Annotation on a Method

Annotations can also be applied to methods.

Example

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Execute {
}

Use it:

class Task {
 
    @Execute
    public void start() {
        System.out.println("Task started");
    }
 
    public void stop() {
        System.out.println("Task stopped");
    }
}

Now reflection can find methods annotated with @Execute.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Execute {
}
 
class Task {
 
    @Execute
    public void start() {
        System.out.println("Task started");
    }
 
    public void stop() {
        System.out.println("Task stopped");
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args) {
 
        Method[] methods = Task.class.getDeclaredMethods();
 
        for (Method method : methods) {
 
            if (method.isAnnotationPresent(Execute.class)) {
 
                System.out.println(
                    "Execute method: " + method.getName()
                );
            }
        }
    }
}

Output

Execute method: start

This technique is conceptually similar to how frameworks discover specially marked methods.

@Inherited

@Inherited allows a class-level annotation to be inherited by subclasses.

Example

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Company {
    
    String name();
}

Apply it to a parent class:

@Company(name = "ABC")
class Parent {
 
}

Subclass:

class Child extends Parent {
 
}

Now:

Company company =
        Child.class.getAnnotation(Company.class);
 
System.out.println(company.name());

Output

ABC

Without @Inherited, class-level annotation inheritance does not occur through this mechanism.

Important

@Inherited applies to class annotations. It does not mean that annotations on methods and fields automatically become inherited.

@Documented

@Documented indicates that an annotation should appear in generated Java documentation when appropriate.

Example

@Documented
@interface DeveloperInfo {
 
    String name();
}

It is mainly useful when creating APIs or libraries where annotation information should be visible in generated documentation.

@Repeatable

@Repeatable allows the same annotation to be applied multiple times to the same declaration.

Example

@Repeatable(Roles.class)
@interface Role {
 
    String value();
}

Container annotation:

@interface Roles {
 
    Role[] value();
}

Now:

@Role("ADMIN")
@Role("USER")
class Employee {
 
}

The same annotation is applied twice.

Annotations on Parameters

Annotations can also be applied to method parameters.

Example

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@interface Required {
}

Usage:

class UserService {
 
    public void createUser(
            @Required String username) {
 
        System.out.println(username);
    }
}

Parameter annotations are commonly used by frameworks for validation, dependency injection, request mapping, and other purposes.

Annotations on Fields

Example

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Important {
}

Usage:

class Employee {
 
    @Important
    private String name;
 
    private int age;
}

Reflection can inspect the fields and check whether @Important is present.

Annotations on Constructors

Example

@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
@interface Inject {
}

Usage:

class Service {
 
    @Inject
    public Service() {
 
    }
}

Frameworks can inspect constructors and use annotations to determine which constructor should be used.

Annotation Processing

Annotations can be processed in different ways.

1. Compiler

The Java compiler can use annotations such as:

@Override

to validate code.

2. IDE

IDEs can use annotations to provide:

  • Warnings
  • Code navigation
  • Suggestions
  • Error highlighting

3. Runtime Reflection

Runtime annotations can be read using reflection.

Example

method.isAnnotationPresent(MyAnnotation.class);

4. Annotation Processors

Annotation processors can inspect source code during compilation and generate additional source files or perform checks.

This technique is used by various Java tools and libraries.

Annotations vs Comments

Annotations and comments are different.

Comment

// This method calculates total

A comment is primarily intended for humans and is not normally processed as program metadata.

Annotation

@Override

An annotation can be processed by the compiler, tools, frameworks, or runtime reflection depending on its definition.

CommentAnnotation
Mainly for humansProvides program metadata
Not normally processed by Java compiler as metadataCan be processed by compiler/tools/frameworks
Uses //, /* */, /** */Uses @
Does not affect program metadata processingCan influence compilation, tools, or framework behavior

Annotations vs Interfaces

An annotation is not the same as an interface.

Interface

interface Printable {
 
    void print();
}

An interface primarily defines a contract that classes can implement.

Annotation

@interface Printable {
}

An annotation defines metadata that can be attached to program elements.

Annotations in Frameworks

Annotations are heavily used in modern Java frameworks.

For example, Spring applications commonly use annotations such as:

@Component
@Service
@Repository
@Controller
@Autowired

A class might look like:

@Service
public class UserService {
 
    public void createUser() {
        System.out.println("User created");
    }
}

The framework can inspect the annotation and use it to determine how the class should be managed.

Similarly, testing frameworks use annotations such as:

@Test

to identify test methods.

This demonstrates an important concept:

An annotation itself generally provides metadata; some other component interprets that metadata and performs the corresponding behavior.

Commonly Used Java Annotations

AnnotationPurpose
@OverrideIndicates overriding
@DeprecatedMarks deprecated API
@SuppressWarningsSuppresses compiler warnings
@FunctionalInterfaceIdentifies a functional interface
@SafeVarargsSuppresses certain varargs warnings
@RetentionDefines annotation lifetime
@TargetDefines where annotation can be applied
@DocumentedIncludes annotation in generated documentation
@InheritedAllows certain class annotations to be inherited
@RepeatableAllows repeated annotations

Important Annotation Interfaces

Java provides annotation-related types in:

java.lang.annotation

Some important types are:

Annotation
ElementType
Retention
RetentionPolicy
Target
Documented
Inherited
Repeatable

Checking Whether an Annotation Exists

Reflection provides:

isAnnotationPresent()

Example

if (Employee.class.isAnnotationPresent(EmployeeInfo.class)) {
    System.out.println("Annotation exists");
}

Output

Annotation exists

Getting All Annotations

We can use:

getAnnotations()

Example

Annotation[] annotations =
        Employee.class.getAnnotations();
 
for (Annotation annotation : annotations) {
    System.out.println(annotation);
}

For annotations that are intended to be visible through reflection, their retention policy needs to support runtime availability.

getAnnotation() vs getDeclaredAnnotation()

Two commonly used methods are:

getAnnotation()

and:

getDeclaredAnnotation()

getAnnotation() can take annotation inheritance into account for applicable class-level annotations.

getDeclaredAnnotation() looks specifically at the annotation declared directly on that element.

Similarly, reflection provides:

getAnnotations()
getDeclaredAnnotations()

The Declared versions focus on annotations declared directly on the element.

Practical Example: Custom Validation Annotation

Let's create a simple annotation to mark fields that are required.

import java.lang.annotation.*;
 
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Required {
}

Create a class:

class User {
 
    @Required
    private String username;
 
    private String email;
 
    User(String username, String email) {
        this.username = username;
        this.email = email;
    }
}

Now a validation utility can inspect the fields:

import java.lang.reflect.Field;
 
class Validator {
 
    static void validate(Object object) throws IllegalAccessException {
 
        Field[] fields = object.getClass().getDeclaredFields();
 
        for (Field field : fields) {
 
            if (field.isAnnotationPresent(Required.class)) {
 
                field.setAccessible(true);
 
                Object value = field.get(object);
 
                if (value == null ||
                    value.toString().isBlank()) {
 
                    System.out.println(
                        field.getName() + " is required"
                    );
                }
            }
        }
    }
}

Usage:

import java.lang.annotation.*;
import java.lang.reflect.Field;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Required {
}
 
class Validator {
 
    static void validate(Object object) throws IllegalAccessException {
 
        Field[] fields = object.getClass().getDeclaredFields();
 
        for (Field field : fields) {
 
            if (field.isAnnotationPresent(Required.class)) {
 
                field.setAccessible(true);
 
                Object value = field.get(object);
 
                if (value == null ||
                    value.toString().isBlank()) {
 
                    System.out.println(
                        field.getName() + " is required"
                    );
                }
            }
        }
    }
}
 
class User {
 
    @Required
    private String username;
 
    private String email;
 
    User(String username, String email) {
        this.username = username;
        this.email = email;
    }
}
 
public class HelloWorld {
 
    public static void main(String[] args)
            throws IllegalAccessException {
 
        User user = new User("", "john@example.com");
 
        Validator.validate(user);
    }
}

Output

username is required

This is a simplified example of how annotation-driven processing can be designed.

Real validation frameworks provide much more functionality and should generally be preferred over building validation infrastructure from scratch for production applications.

Advantages of Annotations

1. Less Configuration

Annotations can keep configuration close to the code it describes.

2. Better Readability

For example:

@Override

immediately communicates the developer's intention.

3. Framework Integration

Annotations are extensively used by Java frameworks.

4. Compile-Time Checking

Some annotations allow the compiler to detect programming mistakes.

5. Runtime Processing

Runtime annotations can be inspected using reflection.

6. Extensibility

Developers can create custom annotations for application-specific requirements.

Disadvantages of Annotations

1. Too Many Annotations Can Reduce Readability

A class containing many annotations can become difficult to understand.

2. Runtime Reflection Can Have Overhead

Applications that heavily rely on runtime reflection can introduce additional complexity and overhead.

3. Hidden Behavior

Frameworks may perform significant operations based on annotations, which can make behavior less obvious to someone unfamiliar with the framework.

4. Incorrect Configuration

An incorrectly configured annotation may cause application startup or runtime problems.

Common Mistakes

Mistake 1: Forgetting Runtime Retention

If you want to read an annotation using reflection:

@Retention(RetentionPolicy.RUNTIME)

is generally required.

Mistake 2: Using the Wrong Target

If:

@Target(ElementType.METHOD)

is specified, the annotation cannot be used on a class.

Mistake 3: Assuming Every Annotation Has Runtime Behavior

An annotation does not automatically execute code.

For example:

@MyAnnotation
class Demo {
}

does not by itself make Java execute anything.

Some compiler, tool, processor, framework, or runtime code must interpret the annotation.

Mistake 4: Using @SuppressWarnings to Hide Real Problems

Avoid blindly writing:

@SuppressWarnings("all")

Instead, suppress only the specific warning when you understand why it is safe.

Mistake 5: Confusing @Inherited with General Inheritance

@Inherited applies to certain class-level annotation inheritance behavior. It does not mean annotations on every method and field are automatically inherited.

Key Points

  • Annotations provide metadata in Java.
  • Annotations start with the @ symbol.
  • Java provides predefined annotations such as @Override and @Deprecated.
  • Developers can create custom annotations using @interface.
  • @Target defines where an annotation can be used.
  • @Retention defines how long the annotation is retained.
  • SOURCE annotations are discarded after compilation.
  • CLASS annotations are stored in class files.
  • RUNTIME annotations can be inspected through reflection.
  • @Inherited can provide inheritance behavior for applicable class annotations.
  • @Repeatable allows an annotation to be used multiple times.
  • Runtime annotations are commonly used by frameworks.
  • Reflection can be used to inspect runtime annotations.
  • Annotation processing can also happen during compilation.
  • An annotation does not automatically execute behavior; something must interpret it.

Frequently Asked Questions

What is an annotation in Java?

An annotation is metadata attached to program elements such as classes, methods, fields, constructors, or parameters.

What symbol is used for annotations?

The @ symbol.

Example

@Override

What is a custom annotation?

A custom annotation is an annotation created by the developer using:

@interface

Example

@interface MyAnnotation {
}

What is @Retention?

@Retention specifies how long an annotation should be retained.

The available policies are:

SOURCE
CLASS
RUNTIME

Which retention policy is required for reflection?

Usually:

RetentionPolicy.RUNTIME

What is @Target?

@Target specifies the program elements on which an annotation can be applied.

Can annotations contain values?

Yes.

Example

@interface Employee {
 
    String name();
}

Usage:

@Employee(name = "John")

Can annotations be inherited?

Some class-level annotations can be inherited when the annotation type is declared with:

@Inherited

Are annotations executed?

Annotations themselves do not normally execute business logic. They provide metadata that can be interpreted by the compiler, tools, annotation processors, frameworks, or runtime code.

Conclusion

Java annotations provide a powerful way to attach metadata to program elements. They are used by the Java compiler, development tools, annotation processors, and frameworks to understand how different parts of an application should be treated.

The most important concepts to remember are:

Annotation
    ↓
Metadata
    ↓
@Target       → Where it can be used
@Retention    → How long it is available
@Inherited    → Applicable class-level inheritance behavior
@Repeatable   → Allows repeated annotations
    ↓
Processing
    ↓
Compiler / Tools / Annotation Processor / Reflection / Framework

Understanding annotations is especially important when working with modern Java frameworks because many frameworks use annotations as a primary mechanism for configuration and behavior.

See you in next page....🙂

← Reflection APIGenerics →
← Reflection APIGenerics →