[JSR308] Suggestion (and example) for annotations that take any annotation or for annotation inheritance
Bill Pugh
pugh at cs.umd.edu
Wed Oct 22 17:10:29 EDT 2008
On Oct 3, 2008, at 1:15 AM, Ciera Jaspan wrote:
> Hi everyone,
>
> I, and several others, have a need for either annotations that can
> take any annotation or (preferably) for annotation inheritance.
> While annotation inheritance is preferred, I understand there may be
> good reasons this was left out of JSR-175 initially. If annotation
> inheritance is not possible, having annotations which can take any
> annotation would at least help. I've provided examples that motivate
> each of these suggestions below, from a static analysis tool we are
> building. Please let me know if you have any questions about the
> examples given, or need further examples for motivation.
I proposed a solution for this a year ago on the 305 and 308 mailing
lists, and I'll resurrect it again.
One of the design features of Java annotations is that there is no
subtyping between annotations. I talked with Josh, and one of the
things that would make changing this hard is methods such as the
following in java.lang.reflect.Method:
T extends Annotation>
T
getAnnotation(Class<T> annotationClass)
Returns this element's annotation for the specified type if
such an annotation is present, else null.
This assumes that for any one place where an annotation could occur,
and any particular annotation class, there is either zero or one
instances of an annotation. This also means, for example, that you
can't apply two difference instances of an annotation, with different
parameters, to an annotation location. For example, you can't do:
@A(1) @A(2) int x;
Given this limitation, here is my proposed solution:
* Proposal 1: An annotation is allowed to extend/implement any number
of interfaces.
You might want to use this for marker interfaces, or define an
interface that defines
several elements/methods, and any annotation that implements that
interface would be
required to provide values for those methods.
Note that the interface would just be a normal interface that could
be implemented by
classes as well. interfaces can't define default values.
This would allow you to define a standard set of element names that
were used by
by set of specific annotations, and allow internal API's that worked
with any annotation
from that set. You could also define an interface that was
implemented both by annotations
and by other, non-annotation based meta-data containers.
* Proposal 2 (requires proposal 1):
An annotation can define an element that returns an interface that
extends
java.lang.annotation.Annotation. When applying such an annotation in
the source code, the
value used there must be some concrete annotation that extends that
interface.
Right now, the only values allowed for annotation elements are:
primitives, String, Class, enums, specific annotation classes, and
arrays
This proposal would allow you to define annotations that, when
applied in source code,
accepted as an element value any one of a number of specific
annotations. By defining the
element to return a value of type Annotation, you can define an
element where an arbitrary
Annotation can be provided. For example, consider example where the
Baz annotation can
be applied with either a Foo or a Baz annotation as an element:
public interface AnnotationWithId extends Annotation {
int id();
}
public @interface Foo extends AnnotationWithId {
int id(); // this could be omitted,
// since it is defined in the interface
String msg();
}
public @interface Bar extends AnnotationWithId {
int id() default 0; // couldn't be omitted,
// since the interface can't give a default value
String date();
}
public @interface Baz {
AnnotationWithId annotation(); // can supply a @Foo or @Bar here
String reason();
}
public Test {
@Baz(annotation=@Foo(id=17, msg="testing"), reason="because")
public int test() { return 17; }
}
Bill Pugh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.csail.mit.edu/pipermail/jsr308/attachments/20081022/3a7690db/attachment.htm
More information about the JSR308
mailing list