How @Target(ElementType.ANNOTATION_TYPE) works

You can use an annotated annotation to create a meta-annotation, for example consider this usage of @Transactional in Spring:

/**
 * Shortcut and more descriptive "alias" for {@code @Transactional(propagation = Propagation.MANDATORY)}.
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(propagation = Propagation.MANDATORY)
public @interface RequiresExistingTransaction {
}

When you enable Spring to process the @Transactional annotation, it will look for classes and methods that carry @Transactional or any meta-annotation of it (an annotation that is annotated with @Transactional).

Anyway this was just one concrete example how one can make use of an annotated annotation. I guess it's mostly frameworks like Spring where it makes sense to use them.


Each annotation annotated by @Target(ElementType.ANNOTATION_TYPE) is called Meta-annotation. That means, you can define your own custom annotations that are an amalgamation of many annotations combined into one annotation to create composed annotations.

A good example from Android world is StringDef

Denotes that the annotated String element, represents a logical type and that its value should be one of the explicitly named constants.

@Retention(SOURCE)
@StringDef({POWER_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE}) 
public @interface ServicesName {}

public static final String POWER_SERVICE = "power";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";

Code inspector will treat @ServicesName and @WeekDays in the same way as @StringDef. As a result we can create as much named StringDef's as we need and override set of constants. @Target(ElementType.ANNOTATION_TYPE) it is a tool that allows to extend the use of annotations.


For example, if annotation looks like

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeAnnotation {

    String description() default "This is example for class annotation";
}

compiler will complane in this situation

@SomeAnnotation
public class SomeClass {

    @SomeAnnotation    // here it's complaning
    public void someMethod(){}
}

If you change

@Target(ElementType.TYPE) 

to

@Target({ElementType.METHOD, ElementType.TYPE}) 

it won't complain anymore.