How to create an instance of an annotation

You could use an annotation proxy such as this one from the Hibernate Validator project (disclaimer: I'm a committer of this project).


Well, it's apparently nothing all that complicated. Really!

As pointed out by a colleague, you can simply create an anonymous instance of the annotation (like any interface) like this:

MyAnnotation:

public @interface MyAnnotation
{

    String foo();

}

Invoking code:

class MyApp
{
    MyAnnotation getInstanceOfAnnotation(final String foo)
    {
        MyAnnotation annotation = new MyAnnotation()
        {
            @Override
            public String foo()
            {
                return foo;
            }

            @Override
            public Class<? extends Annotation> annotationType()
            {
                return MyAnnotation.class;
            }
        };

        return annotation;
    }
}

Credits to Martin Grigorov.


The proxy approach, as suggested in Gunnar's answer is already implemented in GeantyRef:

Map<String, Object> annotationParameters = new HashMap<>();
annotationParameters.put("name", "someName");
MyAnnotation myAnnotation = TypeFactory.annotation(MyAnnotation.class, annotationParameters);

This will produce an annotation equivalent to what you'd get from:

@MyAnnotation(name = "someName")

Annotation instances produced this way will act identical to the ones produced by Java normally, and their hashCode and equals have been implemented properly for compatibility, so no bizarre caveats like with directly instantiating the annotation as in the accepted answer. In fact, JDK internally uses this same approach: sun.reflect.annotation.AnnotationParser#annotationForMap.

The library itself is tiny and has no dependencies (and does not rely on JDK internal APIs).

Disclosure: I'm the developer behind GeantyRef.