JEP 120: Repeating Annotations
Joe Darcy
joe.darcy at oracle.com
Thu Jan 5 15:32:13 PST 2012
On 1/5/2012 1:17 PM, Jesse Glick wrote:
> On 01/05/2012 03:20 PM, Joe Darcy wrote:
>>> @Repeatable
>>> @interface Thing {int value();}
>>
>> ...how the repeated annotations are represented in a class file
>
> The same way multiple annotations of different types are - just as
> separate entries that happen to use the same type_index.
> (JVMS3-DRAFT-20090512.pdf section 4.7.16) In fact I cannot find
> anything in the draft VM spec, or JSR 175 materials, that says it is
> not permitted to have repeating annotations in class files of current
> version! Given the program
>
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> @Retention(RetentionPolicy.RUNTIME)
> @interface Stuff1st {}
>
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> @Retention(RetentionPolicy.RUNTIME)
> @interface Stuff2nd {}
>
> import java.lang.annotation.Annotation;
> @Stuff1st @Stuff2nd
> public class Annotest {
> public static void main(String[] x) {
> for (Annotation a : Annotest.class.getAnnotations()) {
> System.out.println(a);
> }
> }
> }
>
> if you compile it and then replace "2nd" with "1st" in Annotest.class
> with a text editor and then run, you get an AnnotationFormatError from
> sun.reflect.annotation.AnnotationParser.parseAnnotations2 but this
> seems safely within the core library code. In fact the current
> AnnotationParser behavior is arguably a bug - it is enforcing a
> constraint not mentioned in the JVM spec. Deleting this check and
> making Class.annotations a multimap would seem to be all you need on
> the runtime side. (List getAnnotations(Class) and the like would be
> convenient but not strictly necessary.)
To state this more precisely, how are repeating annotations in a class
file represented in such a way that existing clients of logically
repeating annotations behave sensibly and that other consumers of class
files don't have to have extensive modifications.
>
> On the language/compiler side, you would just need to relax section
> 9.7 of the JLS "if a declaration is annotated with more than one
> annotation for a given annotation type" to say "...unless that
> annotation type is annotated with @Repeatable". This seems a simpler
> change than what the JEP currently proposes.
That section of the JLS will have to be updated to allow repeated
annotations under whatever changes are made to annotation type
declarations to allow repeating annotations.
>
>> existing workarounds for the absence of repeated annotations can be
>> smoothly migrated to use the new language idiom
>
> Migration to @Repeatable would be just as smooth for users of an
> existing annotation, whereas code interpreting an annotation - far
> less common - is hardly burdened by searching for multiples.
I disagree. Code cannot reliably migrate to use repeating annotations
unless the code that interprets the repeating annotation is ready to
deal with them. There is a long-standing workaround for the lack of
repeating annotations. I believe any solution to repeating annotations
that did not acknowledge and leverage this situation is unlikely to have
speedy adoption.
> In the case of a newly designed annotation intended for use with a new
> source level, @Repeatable avoids the need to add an extra documented
> type to a public API.
Back in Java SE 5, the JSR 175 expert group explicitly choose not to
allow repeating annotations. If adding this feature was being done in
Java SE 6 rather than Java SE 8, less weight could be given to prior
practice.
-Joe
More information about the compiler-dev
mailing list