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?
In Java SE 6, annotations cannot subclass one another, and an annotation is not allowed to extend/implement any interfaces.
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 { ... }
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.
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.
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 ofClass
, 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 anypublic
orprotected
method declared in classObject
or in the interfaceannotation.Annotation
.
I'm afraid I don't know of a good workaround, but now at least you know why you get the error.
Depending on the reason why you would want to specify other annotations there are multiple solutions:
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();
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With