Java WTF: Reflection API and Annotations

I got some exposure to custom Java 5 Annotations today and came across a noobie mistake.

Here’s my annotation:

public @interface Annotated {
}

Pretty simple, right?

Here’s a test class that uses the annotation:

import java.lang.annotation.Annotation;

@Annotated
public class Main {
    public static void main(String[] args) throws Exception {
        for(Annotation ann: Main.class.getAnnotations()) {
            System.out.println(ann);
        }
    }
}

What does this print?

Nothing!

Well, WTF?

Turns out Annotations are not run-time accessible unless you declaratively specific it via @Retention. The updated annotation looks like this:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Annotated {

}

By default, the Retention is specified with RetentionPolicy.CLASS which, per the javadocs, “Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.”

RetentionPolicy.RUNTIME allows the annotation “to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.”

File this one under, RTFM.

Java WTF: Reflection API and Annotations

Leave a Reply

Your email address will not be published. Required fields are marked *