repeating annotations comments

michael keith michael.keith at oracle.com
Fri Dec 14 13:59:03 PST 2012


Here are some observations from looking at the current state of the 
repeating annotation spec. If I got something wrong, here, I trust 
you'll let me know :-)

1. The getAnnotation(Class<T>) method is being changed to look through 
container annotations. This method returns an Annotation, i.e. a single 
instance, so applying it to repeated ones is necessarily going to have 
to return only one. But having it look through container annotation ends 
up not being very productive, and may be causing it to be 
counter-productive.

Look-through for this method is not productive because the call is being 
made precisely in the legacy cases when only one annotation was 
expected, but a container annotation will only be synthesized when 
multiples are present. So look-through does not really help get "the" 
expected annotation. The only case when it would be useful is in the 
unlikely case when the container annotation is used explicitly and 
contains a single contained annotation.

It may be counter-productive for three reasons.
The first is because getting a random single annotation in the presence 
of multiples is potentially dangerous since the calling code will 
continue without knowing that multiples are present, so legacy code is 
essentially broken, but will not actually fail. It will just be 
semantically incorrect.
The second is because I didn't see (and I may just have missed it) where 
it was defined that if both T and TC were present that T would be 
guaranteed to be returned and not some instance within TC. Example 1.2-3 
shows this to be the case but I didn't see that it was specified 
behavior rather than just because the T occurred before the TC. If the 
example had been TC and then T would the instance of T be returned? This 
could be important because existing code to handle this case checks for 
the container annotation TC and then checks for the single annotation T. 
However, if checking for T happens to look through TC and return one of 
the contained annotations in TC instead of the lone T annotation then 
the lone annotation would not get found.
The third is because all of the code that is currently out there that 
needs to check for the previous case, i.e. both T and TC occurring, will 
get a false positive in the simpler case of multiple instances of T 
annotations (as per the second part of example 1.2-1 in the doc). The 
getAnnotation(TC) will return the synthesized TC containing all of the 
instances of T, and then getAnnotation(T) will return one of those same 
instances again. Legacy code will assume that the result of 
getAnnotation(T) is disjoint from the contained annotations of the TC 
returned by getAnnotation(TC).
Note: The same argument applies to the isAnnotationPresent(T) method 
since it is defined in terms of getAnnotation(T).

2. Given that get[Declared]Annotations() is going to change and return 
multiple instances of the same annotation (rather than a single instance 
of a container annotation) existing implementations are going to have to 
be fixed since there is no backwards compatibility there at all.

3. In general, it appears that once an annotation is made repeatable the 
annotation processing code is inevitably going to have to change in 
order to handle the repeatability. We were willing to take that hit, 
particularly since the new behavior requires opting in, and that means 
that specs could do so at their own discretion. However, the code to 
handle both the new and the old (i.e. be able to process both new 
repeatable annotations as well as the older idiomatic container 
annotations) is a little less intuitive to write than I had hoped it 
would be. The easiest way might just be to create a Set of instances to 
avoid duplicates. Not rocket science, just not what I would have expected.

Thanks,
-Mike





More information about the enhanced-metadata-spec-discuss mailing list