Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Annotation member which holds other annotations?

I want to create a custom annotation (using Java) which would accept other annotations as parameter, something like:

public @interface ExclusiveOr {
    Annotation[] value();
}

But this causes compiler error "invalid type for annotation member".

Object[] also doesn't work.

Is there a way to do what I want?

like image 988
ivan_ivanovich_ivanoff Avatar asked Mar 24 '09 20:03

ivan_ivanovich_ivanoff


People also ask

Can an annotation extend another annotation Java?

In Java SE 6, annotations cannot subclass one another, and an annotation is not allowed to extend/implement any interfaces.

Can we apply two annotations together?

It is also possible to use multiple annotations on the same declaration: @Author(name = "Jane Doe") @EBook class MyClass { ... } If the annotations have the same type, then this is called a repeating annotation: @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }

What is the use of @interface annotation?

Annotation is defined like a ordinary Java interface, but with an '@' preceding the interface keyword (i.e., @interface ). You can declare methods inside an annotation definition (just like declaring abstract method inside an interface). These methods are called elements instead.

What is @target annotation in Java?

If an @Target meta-annotation is present, the compiler will enforce the usage restrictions indicated by ElementType enum constants, in line with JLS 9.7. 4. For example, this @Target meta-annotation indicates that the declared type is itself a meta-annotation type.


2 Answers

The error is produced because you can't use interfaces as annotation values (change it to Comparable and you'll get the same error). From the JLS:

It is a compile-time error if the return type of a method declared in an annotation type is any type other than one of the following: one of the primitive types, String, Class and any invocation of Class, an enum type, an annotation type, or an array of one of the preceding types. It is also a compile-time error if any method declared in an annotation type has a signature that is override-equivalent to that of any public or protected method declared in class Object or in the interface annotation.Annotation.

I'm afraid I don't know of a good workaround, but now at least you know why you get the error.

like image 66
Michael Myers Avatar answered Sep 20 '22 05:09

Michael Myers


Depending on the reason why you would want to specify other annotations there are multiple solutions:

An array of instances of a single annotation type

Probably not what you meant in your question, but if you want to specify multiple instances of a single annotation type it's certainly possible:

public @interface Test {
    SomeAnnotation[] value();
}

An array of annotation types instead of instances

If you do not need to specify any parameters on the individual annotations you can just user their class objects instead of instances.

public @interface Test {
    Class<? extends Annotation>[] value();
}

But an enum would of course also do the trick in most situations.

Use multiple arrays

If the set of possible annotation types you want to use is limited, you can create a separate parameter for each one.

public @interface Test {
    SomeAnnotation[] somes() default { };
    ThisAnnotation[] thiss() default { };
    ThatAnnotation[] thats() default { };
}

Giving a default value to each member makes it possible to only specify arrays for the types you need.

like image 29
Feuermurmel Avatar answered Sep 19 '22 05:09

Feuermurmel