JEP 120: Repeating Annotations

Jesse Glick jesse.glick at oracle.com
Thu Jan 5 13:17:04 PST 2012


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.)

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.

> 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. 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.

I do not think this is a terribly important issue, just trying to understand the motivation for the current design decision. (Speaking as someone who has worked with a 
lot of semantically repeatable annotations.)




More information about the compiler-dev mailing list