JDK 8 (initial) RFR for JDK-8005294 : Consider default methods for additions to AnnotatedElement

Peter Levart peter.levart at gmail.com
Fri Oct 25 15:56:14 UTC 2013


Hi Joe,

The code below is more optimal only in AnnotatedElement implementations 
that don't override getDeclaredAnnotation(Class) with more optimal 
implementation based on a HashMap lookup. Your implementation avoids 
calling getDeclaredAnnotations() in common cases (where only directly 
present or only in-directly present annotations exist), but as this is a 
default method, it must be assumed that it will be invoked on 
AnnotatedElement implementations that don't override it and those 
presumably also don't override  default getDeclaredAnnotation(Class) 
which is based on getDeclaredAnnotations() and interation over returned 
elements. In this situation, your code does 2 (or in uncommon case 3) 
calls to getDeclaredAnnotations() with iteration over elements, while 
the below code only does 1...

On 10/25/2013 05:03 PM, Peter Levart wrote:
> Hi Joe,
>
> I propose some "premature" optimization for 
> AnnotatedElement.getDeclaredAnnotationsByType(). This implementation 
> calls either getDeclaredAnnotatios() once or 
> getDeclaredAnnotation(Class) once, depending on whether the annotation 
> type is repeatable or not respectively (this check also requires a 
> getDeclaredAnnotation() call, but I propose to extend AnnotationType 
> in the future to provide with cached containerClass directly). Also, 
> it is about 7x faster to use annotationClass.isInstance(ann) to check 
> for the type of annotation instead of ann.annotationType() == 
> annotationClass which goes through annotation Proxy, etc...
>
> Here it is:
>
>     default <T extends Annotation> T[] 
> getDeclaredAnnotationsByType(Class<T> annotationClass) {
>         Objects.requireNonNull(annotationClass);
>         Repeatable repeatable = 
> annotationClass.getDeclaredAnnotation(Repeatable.class);
>
>         // non-repeatable: just delegate to getDeclaredAnnotation and 
> return wrapped result
>         if (repeatable == null) {
>             T ann = getDeclaredAnnotation(annotationClass);
>             @SuppressWarnings("unchecked")
>             T[] result = (T[]) Array.newInstance(annotationClass, ann 
> == null ? 0 : 1);
>             if (ann != null) result[0] = ann;
>             return result;
>         }
>
>         // repeatable: iterate all declared annotations, find directly 
> and indirectly present
>         // and also determine the order (directlyPresentFirst)...
>         Class<? extends Annotation> containerClass = repeatable.value();
>         T directlyPresent = null;
>         T[] indirectlyPresent = null;
>         boolean directlyPresentFirst = false;
>         for (Annotation ann : getDeclaredAnnotations()) {
>             if (directlyPresent == null && 
> annotationClass.isInstance(ann)) {
>                 directlyPresent = annotationClass.cast(ann);
>                 if (indirectlyPresent != null) {
>                     break;
>                 }
>             } else if (indirectlyPresent == null && 
> containerClass.isInstance(ann)) {
>                 indirectlyPresent = AnnotationSupport.getValueArray(ann);
>                 if (directlyPresent != null) {
>                     directlyPresentFirst = true;
>                     break;
>                 }
>             }
>         }
>
>         // concatenate directlyPresent and indirectlyPresent annotations
>         @SuppressWarnings("unchecked")
>         T[] result = (directlyPresent == null && indirectlyPresent != 
> null)
>                      ? indirectlyPresent
>                      : (T[]) Array.newInstance(annotationClass,
>                          (directlyPresent == null ? 0 : 1) +
>                          (indirectlyPresent == null ? 0 : 
> indirectlyPresent.length));
>
>         if (directlyPresent != null) {
>             if (indirectlyPresent == null || indirectlyPresent.length 
> == 0) {
>                 result[0] = directlyPresent;
>             } else {
>                 result[directlyPresentFirst ? 0 : 
> indirectlyPresent.length] = directlyPresent;
>                 System.arraycopy(indirectlyPresent, 0, result,
>                     directlyPresentFirst ? 1 : 0, 
> indirectlyPresent.length);
>             }
>         }
>
>         return result;
>     }
>
>
>
> Regards, Peter
>
> On 10/25/2013 10:40 AM, Joe Darcy wrote:
>> Hi Joel and Peter,
>>
>> On 10/24/2013 07:10 AM, Peter Levart wrote:
>>> Hi Joe,
>>>
>>> I see two problems with the implementation in 
>>> *AnnotatedElementSupport*. The first is the treatment of 
>>> declared-only annotations where the code returns either directly 
>>> present or in-directly present repeatable annotations, but not both. 
>>> So in the following example:
>>>
>>> @Ann(1)
>>> @AnnCont({@Ann(2), @Ann(3)})
>>>
>>> it will only return [@Ann(1)], but I think it should return all of 
>>> them [@Ann(1), @Ann(2), @Ann(3)] - does the spec. define that?
>>>
>>
>> [snip]
>>
>> From your feedback (and a closer reading of the specifciation), I've 
>> reworked the specifications and implemenations of the default methods 
>> for get[Declared]AnnotationsByType:
>>
>> http://cr.openjdk.java.net/~darcy/8005294.2/
>>
>> Tests still need to be written, but this implementation should be 
>> much closed to what is needed.
>>
>> Thanks,
>>
>> -Joe
>




More information about the core-libs-dev mailing list