A runtime annotation stores small metadata that reflection can read later.

annotation type An annotation type declares the metadata fields that can be attached to a program element.
runtime retention Runtime retention keeps annotation metadata available to reflection while the program runs.

Custom Annotation

bonus
CustomAnnotation.java
Replay: real traced execution (multi-file project)
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface Lesson {
    String name();
    int level();
}

@Lesson(name = "reflection", level = 2)
class AnnotatedExample {
}

public class CustomAnnotation {
    public static void main(String[] args) {
        int bonus = 0;
        Lesson lesson = AnnotatedExample.class.getAnnotation(Lesson.class);
        int adjustedLevel = lesson.level() + bonus;

        System.out.println("name=" + lesson.name());
        System.out.println("level=" + adjustedLevel);
    }
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface Lesson {
    String name();
    int level();
}

@Lesson(name = "reflection", level = 2)
class AnnotatedExample {
}

public class CustomAnnotation {
    public static void main(String[] args) {
        int bonus = 1;
        Lesson lesson = AnnotatedExample.class.getAnnotation(Lesson.class);
        int adjustedLevel = lesson.level() + bonus;

        System.out.println("name=" + lesson.name());
        System.out.println("level=" + adjustedLevel);
    }
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface Lesson {
    String name();
    int level();
}

@Lesson(name = "reflection", level = 2)
class AnnotatedExample {
}

public class CustomAnnotation {
    public static void main(String[] args) {
        int bonus = 3;
        Lesson lesson = AnnotatedExample.class.getAnnotation(Lesson.class);
        int adjustedLevel = lesson.level() + bonus;

        System.out.println("name=" + lesson.name());
        System.out.println("level=" + adjustedLevel);
    }
}
  1. bonus ← 0, lesson ← @Lesson(name="reflection", level=2), adjustedLevel ← 2

    14public class CustomAnnotation {15    public static void main(String[] args) {16        int bonus→ 0 = 0;  //@bonus=1, 317        Lesson lesson→ @Lesson(name="reflection", level=2) = AnnotatedExample.class.getAnnotation(Lesson.class);18        int adjustedLevel→ 2 = lesson.level() + bonus0;1920        System.out.println("name=" + lesson.name());21        System.out.println("level=" + adjustedLevel2);22    }
    outputname=reflection
    level=2
  1. bonus ← 1, lesson ← @Lesson(name="reflection", level=2), adjustedLevel ← 3

    14public class CustomAnnotation {15    public static void main(String[] args) {16        int bonus→ 1 = 1;17        Lesson lesson→ @Lesson(name="reflection", level=2) = AnnotatedExample.class.getAnnotation(Lesson.class);18        int adjustedLevel→ 3 = lesson.level() + bonus1;1920        System.out.println("name=" + lesson.name());21        System.out.println("level=" + adjustedLevel3);22    }
    outputname=reflection
    level=3
  1. bonus ← 3, lesson ← @Lesson(name="reflection", level=2), adjustedLevel ← 5

    14public class CustomAnnotation {15    public static void main(String[] args) {16        int bonus→ 3 = 3;17        Lesson lesson→ @Lesson(name="reflection", level=2) = AnnotatedExample.class.getAnnotation(Lesson.class);18        int adjustedLevel→ 5 = lesson.level() + bonus3;1920        System.out.println("name=" + lesson.name());21        System.out.println("level=" + adjustedLevel5);22    }
    outputname=reflection
    level=5