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

Joe Darcy joe.darcy at oracle.com
Fri Oct 25 19:05:47 UTC 2013


Hi Peter,

On 10/25/2013 05:28 AM, Peter Levart wrote:
> On 10/25/2013 12:29 PM, Peter Levart wrote:
>>
>> Hi Joe,
>>
>> So, the order must be respected, right.
>>
>> There's a bug. I think you wanted to call:
>>
>> ((Class) this).getSuperclass()
>>
>> Instead of:
>>
>> thisClass.getSuperclass()
>>
>> ...which would always return Object.class...
>>
>
> Well, this is not the only change needed, of course. What about 
> something like the following (prefer iteration to recursion and use 
> AnnotationType.isInherited() which is faster):
>
>
>     default <T extends Annotation> T[] getAnnotationsByType(Class<T> 
> annotationClass) {
>         T[] result = getDeclaredAnnotationsByType(annotationClass);
>         if (result.length == 0 && this instanceof Class &&
> AnnotationType.getInstance(annotationClass).isInherited()) {
>             for (Class<?> clazz = ((Class<?>) this).getSuperclass();
>                  clazz != null; clazz = clazz.getSuperclass()) {
>                 result = 
> clazz.getDeclaredAnnotationsByType(annotationClass);
>                 if (result.length > 0) {
>                     break;
>                 }
>             }
>         }
>         return result;
>     }
>

Mulling over your suggested code, I've come up with

     default <T extends Annotation> T[] getAnnotationsByType(Class<T> 
annotationClass) {
         /*
          * Definition of associated: directly or indirectly present OR
          * neither directly nor indirectly present AND the element is
          * a Class, the annotation type is inheritable, and the
          * annotation type is associated with the superclass of the
          * element.
          */
         T[] result = getDeclaredAnnotationsByType(annotationClass);

         if (result.length == 0 && // Neither directly nor indirectly 
present
             this instanceof Class && // the element is a class
AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
             Class<?> clazz = ((Class<?>) this).getSuperclass();
             if (clazz != null) {
                 // Determine if the annotation is associated with the
                 // superclass
                 result = clazz.getAnnotationsByType(annotationClass);
             }
         }

         return result;
     }

This version has the structure of being "obviously correct" since the 
sequence of checks in the code closely follows the definition of 
associated used in AnnotatedElement. While the code you have to directly 
climb the superclass chain should be correct, I'd prefer to simply 
delegate to whatever getAnnotationsByType implementation is being used 
by java.lang.Class (which would not necessarily be this one).

In terms of stack overflow concerns, if this implementation were used by 
java.lang.Class, the stack size is small and should easily be able to 
accomodate even very long superclass chains dozens of levels deep.

Thanks for the feedback,

-Joe



More information about the core-libs-dev mailing list