Master Java Annotations: From Basics to Practical Reflection Usage

This guide explains Java's annotation feature, covering its definition, common uses, meta‑annotations, retention policies, target elements, and provides a complete example that demonstrates custom annotations for field initialization and validation using reflection.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Master Java Annotations: From Basics to Practical Reflection Usage

Annotation Overview

Annotations, introduced in Java 5 and located in the java.lang.annotation package, provide a type‑safe way to attach metadata to program elements such as classes, methods, fields, and parameters. The metadata does not affect the program logic directly but can be processed at compile time or at runtime via reflection for documentation, configuration, validation, or code generation.

Common Uses

Generating documentation (e.g., @author, @param).

Replacing configuration files (e.g., Spring MVC annotations).

Compile‑time checks (e.g., @Override).

Code‑generation tools such as Lombok ( @Data).

Defining an Annotation

Annotations are declared with @interface and implicitly extend java.lang.Annotation.

Members may be public or have default visibility.

Allowed member types are primitive types, String, Enum, Class, other annotations, and arrays of these types.

Annotation information is retrieved at runtime via the Java reflection API.

An annotation may have no members, serving as a marker.

Meta‑annotations

Meta‑annotations annotate other annotations. The core meta‑annotations defined in java.lang.annotation are: @Documented – include the annotation in Javadoc. @Retention – specify how long the annotation is retained ( SOURCE, CLASS, RUNTIME). @Target – define the program elements the annotation can be applied to. @Inherited – allow subclass inheritance of the annotation when applied to a class. @Repeatable – enable multiple instances of the same annotation (Java 8).

Retention Policies

@Retention(RetentionPolicy.SOURCE)

The three policies are: RetentionPolicy.SOURCE: discarded after compilation (e.g., @Override). RetentionPolicy.CLASS: stored in the class file but not available at runtime. RetentionPolicy.RUNTIME: retained at runtime and accessible via reflection (commonly used for custom annotations).

Target Elements

@Target(ElementType.TYPE)

Possible ElementType values include: TYPE – class, interface, enum, annotation type. CONSTRUCTOR – constructors. FIELD – fields (including enum constants). LOCAL_VARIABLE – local variables. METHOD – methods. PACKAGE – packages. PARAMETER – method parameters. ANNOTATION_TYPE – other annotations. TYPE_PARAMETER – type parameters (Java 8). TYPE_USE – any use of a type (Java 8).

Practical Example

Custom Annotations

/**
 * Gender assignment
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@Inherited
public @interface InitSex {
    enum SEX_TYPE { MAN, WOMAN }
    SEX_TYPE sex() default SEX_TYPE.MAN;
}

/**
 * Age validation
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@Inherited
public @interface ValidateAge {
    int min() default 18;
    int max() default 99;
    int value() default 20;
}

Data Model

public class User {
    private String username;
    @ValidateAge(min = 20, max = 35, value = 22)
    private int age;
    @InitSex(sex = InitSex.SEX_TYPE.MAN)
    private String sex;
    // getters and setters omitted for brevity
}

Test Execution

import java.lang.reflect.Field;

public class TestInitParam {
    public static void main(String[] args) throws IllegalAccessException {
        User user = new User();
        initUser(user);
        boolean checkResult = checkUser(user);
        printResult(checkResult);
        // modify age and re‑check
        user.setAge(22);
        checkResult = checkUser(user);
        printResult(checkResult);
    }

    static void initUser(User user) throws IllegalAccessException {
        Field[] fields = User.class.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(InitSex.class)) {
                InitSex init = field.getAnnotation(InitSex.class);
                field.setAccessible(true);
                field.set(user, init.sex().toString());
                System.out.println("Completed attribute modification, value: " + init.sex());
            }
        }
    }

    static boolean checkUser(User user) throws IllegalAccessException {
        Field[] fields = User.class.getDeclaredFields();
        boolean result = true;
        for (Field field : fields) {
            if (field.isAnnotationPresent(ValidateAge.class)) {
                ValidateAge va = field.getAnnotation(ValidateAge.class);
                field.setAccessible(true);
                int age = (int) field.get(user);
                if (age < va.min() || age > va.max()) {
                    result = false;
                    System.out.println("Age value does not meet criteria");
                }
            }
        }
        return result;
    }

    static void printResult(boolean checkResult) {
        if (checkResult) {
            System.out.println("Validation passed");
        } else {
            System.out.println("Validation failed");
        }
    }
}

Running the program produces output similar to:

Completed attribute modification, value: MAN
Age value does not meet criteria
Validation failed
Validation passed

Additional Notes

In production code, annotations are often combined with interceptors or aspect‑oriented programming (AOP) to implement cross‑cutting concerns such as validation, logging, or transaction management.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaReflectionannotationsMeta-annotations
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.