Java Annotations and Reflection

Part 1: Annotations

What is an Annotation?

An annotation is like a tag or label.

You can put it on classes, methods, or variables.

It gives information to the Java compiler or tools.

Example from Daily Life

Think of price tags in a store.

They give extra information: price, size, brand.

The item still works without the tag, but the tag helps.

Built-in Annotations

Java has some built-in annotations:

Example:


class Animal {
    void makeSound() {
        System.out.println("Sound");
    }
}

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

The @Override tells Java: “This method replaces a method from the parent.”


Creating Your Own Annotation

You can also make your own annotations!

Example:


import java.lang.annotation.*;

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

This annotation can be put on methods.


Part 2: Reflection

What is Reflection?

Reflection is a way to look at code while the program is running.

You can inspect classes, methods, and annotations.

You can even change things or call methods.

Example from Daily Life

Imagine looking at your washing machine’s manual.

You see its parts, settings, and instructions.

Reflection is like opening the manual of a Java class.

Basic Example:


public class Hello {
    public void sayHi() {
        System.out.println("Hi!");
    }
}
  

Using Reflection:


import java.lang.reflect.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("Hello");
        Object obj = clazz.getDeclaredConstructor().newInstance();
        Method method = clazz.getMethod("sayHi");
        method.invoke(obj); // prints Hi!
    }
}
  

This code finds the class, creates an object, and calls a method.


Using Reflection with Annotations

Let’s say we use our @RunThis annotation:


public class Task {
    @RunThis
    public void doWork() {
        System.out.println("Work started...");
    }

    public void ignoreThis() {
        System.out.println("Ignore this.");
    }
}
  

Now use reflection to call only methods with @RunThis:


import java.lang.reflect.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Task.class;
        Object obj = clazz.getDeclaredConstructor().newInstance();

        for (Method m : clazz.getDeclaredMethods()) {
            if (m.isAnnotationPresent(RunThis.class)) {
                m.invoke(obj);
            }
        }
    }
}
  

This will only run the doWork() method.


Why Use These?


Conclusion

Annotations are like labels for your code.

Reflection is a way to look inside and work with that code.

Together, they help build smart, flexible programs.

They are used in real tools, tests, and web frameworks.

Start small, practice often, and you’ll master them!