Java Annotations

Metadata for Java code elements

🏷️ What are Annotations?

Annotations provide metadata about program elements like classes, methods, and variables. They don't directly affect program execution but provide information to compilers and tools.


// Basic annotation usage
@Override
public String toString() {
    return "Custom string representation";
}
                                    

Purpose:

@Override ensures method properly overrides parent method

Compiler checks for correct method signature

Common Annotations

🔄

@Override

Indicates method overriding

@Override
public String toString() { }
⚠️

@Deprecated

Marks outdated elements

@Deprecated
public void oldMethod() { }
🔇

@SuppressWarnings

Suppresses compiler warnings

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

@FunctionalInterface

Marks functional interfaces

@FunctionalInterface
interface Calculator { }

🔹 Built-in Annotations Example

Using common Java annotations in practice:

class Animal {
    @Deprecated
    public void makeSound() {
        System.out.println("Some sound");
    }
    
    public void makeNoise() {
        System.out.println("Animal noise");
    }
}

class Dog extends Animal {
    @Override
    public void makeNoise() {
        System.out.println("Woof!");
    }
    
    @SuppressWarnings("deprecation")
    public void testDeprecated() {
        makeSound(); // Using deprecated method
    }
}

// Usage
Dog dog = new Dog();
dog.makeNoise(); // Calls overridden method

Output:

Woof!

@Override ensures correct method signature

@Deprecated warns about old method usage

🔹 Custom Annotations

Creating your own annotations for specific needs:

import java.lang.annotation.*;

// Custom annotation definition
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestMethod {
    String description() default "";
    int priority() default 1;
}

// Using custom annotation
public class TestClass {
    
    @TestMethod(description = "Tests addition", priority = 1)
    public void testAdd() {
        System.out.println("Testing addition");
    }
    
    @TestMethod(description = "Tests subtraction", priority = 2)
    public void testSubtract() {
        System.out.println("Testing subtraction");
    }
}

// Reading annotations at runtime
public class AnnotationProcessor {
    public static void processAnnotations(Class<?> clazz) {
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(TestMethod.class)) {
                TestMethod annotation = method.getAnnotation(TestMethod.class);
                System.out.println("Method: " + method.getName());
                System.out.println("Description: " + annotation.description());
                System.out.println("Priority: " + annotation.priority());
            }
        }
    }
}

Output:

Method: testAdd

Description: Tests addition

Priority: 1

🔹 Meta-Annotations

Annotations that annotate other annotations:

// Meta-annotations for custom annotation
@Retention(RetentionPolicy.RUNTIME) // Available at runtime
@Target({ElementType.TYPE, ElementType.METHOD}) // Can be used on classes and methods
@Documented // Include in JavaDoc
@Inherited // Inherited by subclasses
public @interface MyAnnotation {
    String value();
    int count() default 1;
}

// Using the annotation
@MyAnnotation(value = "Class level", count = 5)
public class AnnotatedClass {
    
    @MyAnnotation("Method level")
    public void annotatedMethod() {
        System.out.println("This method is annotated");
    }
}

// Checking retention policy
public class RetentionExample {
    public static void main(String[] args) {
        Class<AnnotatedClass> clazz = AnnotatedClass.class;
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("Value: " + annotation.value());
            System.out.println("Count: " + annotation.count());
        }
    }
}

Output:

Value: Class level

Count: 5

🧠 Test Your Knowledge

What does the @Override annotation do?