Corporate Training
Request Demo
Click me
Menu
Let's Talk
Request Demo

Tutorials

Annotations and Reflection

24. Annotations and Reflection

Annotations and reflection are two powerful features in Java that provide the ability to add metadata to code and inspect it at runtime. Annotations allow you to attach metadata to program elements (such as classes, methods, and fields), while reflection enables you to inspect and manipulate classes, methods, fields, and other program elements at runtime. In this Core Java tutorial, we'll explore annotations and reflection in detail, providing explanations and examples.

Annotations

Annotations, introduced in Java 5, provide a way to add metadata to your code. They are used for various purposes, including code documentation, compile-time checks, and runtime processing. Annotations are defined using the '@' symbol followed by the annotation name.

Predefined Annotations:

Java provides several predefined annotations, such as '@Override' , '@Deprecated', and '@SuppressWarnings'. These annotations are used to provide additional information to the compiler or runtime environment.

Example of Using Predefined Annotations:
class Example {

    @Override
    public String toString() {
        return "An example object";
    }

    @Deprecated
    public void deprecatedMethod() {
        // Deprecated method implementation
    }

    @SuppressWarnings("unchecked")
    public void uncheckedMethod() {
        // Suppress unchecked warnings
    }
}
 

Custom Annotations:

You can also create custom annotations to define your own metadata. Custom annotations are declared using the '@interface' keyword.

Example of Creating a Custom Annotation:
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value() default "Default value";
    int count() default 1;
}
 

In this example, we define a custom annotation called 'MyAnnotation'  with two elements: 'value' and 'count'.

Using Custom Annotations:
class MyClass {

    @MyAnnotation(value = "Custom value", count = 5)
    public void myMethod() {
        // Custom method implementation
    }
}
 

Reflection:

Reflection is a feature in Java that allows you to inspect and manipulate classes, methods, fields, and other program elements at runtime. It provides classes in the 'java.lang.reflect' package for this purpose.

Example of Using Reflection:
import java.lang.reflect.*;

class MyClass {
    private String privateField;

    public void publicMethod() {
        System.out.println("Public method");
    }

    private void privateMethod() {
        System.out.println("Private method");
    }
}

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        Class clazz = MyClass.class;

        // Get all methods, including private ones
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("Method name: " + method.getName());
            System.out.println("Is private: " + Modifier.isPrivate(method.getModifiers()));
        }

        // Access private field
        Field field = clazz.getDeclaredField("privateField");
        field.setAccessible(true);
        MyClass instance = new MyClass();
        field.set(instance, "Reflection");
        System.out.println("Private field value: " + field.get(instance));
    }
}
 

In this example, we use reflection to inspect the methods and fields of the 'MyClass' class. We also access and modify a private field using reflection.

Reflection and Annotations:

Reflection can be combined with annotations to process annotated elements at runtime. For example, you can use reflection to discover methods or fields annotated with a custom annotation and perform specific actions based on the annotation's metadata.

Conclusion:

Annotations and reflection are powerful features in Java that provide flexibility and extensibility to your code. Annotations allow you to attach metadata to program elements, while reflection enables you to inspect and manipulate classes and their members at runtime. However, both annotations and reflection should be used judiciously, as they can make code more complex and less readable when overused.