Annotations

Annotations

A school program needs reliable data and clear rules. An annotation attaches structured information to a declaration. Tools or runtime code may use it, depending on its retention and the code that reads it.

  1. Understand

    An annotation attaches structured information to a declaration.

  2. Apply

    Trace the Java example, predict its output and explain the result before running it.

  3. Avoid mistakes

    An annotation does not execute an action by itself. Override asks the compiler to check an overriding relationship.

Annotations

Java Annotations are one of those features that quietly power many of Java’s most powerful frameworks—like Spring, Hibernate, and JUnit—yet they often get misunderstood or overlooked by beginners. In this tutorial, we’ll explore what annotations are, why they exist, and how to use them effectively in your programs.

What are Java Annotations?

Annotations in Java are a special kind of metadata that provide information about the code but do not directly affect its execution. They act like notes to the compiler or runtime, guiding them on how to treat the annotated elements (classes, methods, variables, etc.).

Why Use Annotations?

Before annotations, developers relied heavily on XML configuration files or marker interfaces. Annotations offer:

  • Better readability and less clutter
  • Compile-time error checking
  • Cleaner and more maintainable code
  • Support for tools and frameworks that process metadata

Built-in Annotations in Java

Java provides several built-in annotations, especially useful for compile-time checks.

@Override

Indicates that a method is intended to override a method in a superclass.

class Animal {
    void speak() {
        System.out.println("Animal speaks");
    }
}

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

@Deprecated

Marks a method or class as outdated, warning developers to avoid using it.

class LegacyCode {
    @Deprecated
    void oldMethod() {
        System.out.println("Old method, avoid using.");
    }
}

@SuppressWarnings

Instructs the compiler to suppress specific warnings.

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

Meta-Annotations

Java also provides meta-annotations that annotate other annotations:

  • @Target – Specifies the kinds of elements an annotation can be applied to.
  • @Retention – Indicates how long annotations are retained (SOURCE, CLASS, or RUNTIME).
  • @Documented – Marks an annotation for inclusion in the generated JavaDoc.
  • @Inherited – Allows subclasses to inherit the annotation from a superclass.

Creating Custom Annotations

Let’s see how you can define your own annotation:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface LogExecutionTime {
}

Now, apply this annotation to a method:

class Demo {
    @LogExecutionTime
    void run() {
        System.out.println("Running method...");
    }
}

Accessing Annotations at Runtime (Reflection)

Using Java Reflection API, we can process annotations at runtime.

import java.lang.reflect.Method;

class AnnotationProcessor {
    public static void main(String[] args) throws Exception {
        Demo d = new Demo();
        Method m = d.getClass().getMethod("run");

        if (m.isAnnotationPresent(LogExecutionTime.class)) {
            long start = System.currentTimeMillis();
            m.invoke(d);
            long end = System.currentTimeMillis();
            System.out.println("Execution time: " + (end - start) + "ms");
        }
    }
}
Running method...
Execution time: Xms

Real-World Use Cases

Annotations are not just academic—they are used widely in:

  • Spring Framework – @Autowired, @Component, @Service
  • Hibernate – @Entity, @Table, @Id
  • JUnit – @Test, @Before, @After

Summary

  • Annotations are a way to add metadata to Java code.
  • They improve readability and tool support.
  • You can create your own annotations and use reflection to act on them.

Important boundaries and mistakes

An annotation does not execute an action by itself. Override asks the compiler to check an overriding relationship.

Try the school example

Before running this Java program, write down each line you expect to see. Identify the value, branch, object or exception responsible for each line. Then explain whether the following assumption is valid: An annotation does not execute an action by itself.

Java 17 · Main.java · complete practice program

public class Main  {
  static abstract class Person  {
    abstract String role();
  }
  static class Teacher extends Person  {
    @Override String role()  {
      return "Teacher";
    }
  }
  public static void main(String[] args)  {
    System.out.println(new Teacher().role());
  }
}

Worked answer and reasoning

Java 17 · Main.java · source repeated for this answer

public class Main  {
  static abstract class Person  {
    abstract String role();
  }
  static class Teacher extends Person  {
    @Override String role()  {
      return "Teacher";
    }
  }
  public static void main(String[] args)  {
    System.out.println(new Teacher().role());
  }
}

Expected output

Teacher

An annotation attaches structured information to a declaration. Tools or runtime code may use it, depending on its retention and the code that reads it.

An annotation does not execute an action by itself. Override asks the compiler to check an overriding relationship.

Run with javac Main.java, then java Main. The declaration inside Main keeps the helper type available to this standalone example.

Check your understanding

For the complete practice program in this lesson, which output is expected on Java 17?
Choose one answer. You can try again.

Answer and explanation

Teacher

An annotation attaches structured information to a declaration. Tools or runtime code may use it, depending on its retention and the code that reads it. An annotation does not execute an action by itself. Override asks the compiler to check an overriding relationship.

What to remember

An annotation attaches structured information to a declaration. Tools or runtime code may use it, depending on its retention and the code that reads it. An annotation does not execute an action by itself. Override asks the compiler to check an overriding relationship.

Related explanations: Java Variables, Java If Statement - Syntax and Examples, Java Class - Blueprint of Objects, Exceptions in Java Introduction.

Supporting documentation: Official Java learning guide and Java 17 language specification.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Logging →