Proposal to make new-in-Java-SE-8 methods on AnnotatedElement default methods

Joe Darcy joe.darcy at oracle.com
Fri Oct 25 01:35:31 PDT 2013


Hello,

Second iterations of @implSpec's for get[Declared]AnnotationsByType 
interspersed below:

On 10/24/2013 11:37 AM, Alex Buckley wrote:
> On 10/24/2013 8:34 AM, Joel Borggrén-Franck wrote:
>> On 24 okt 2013, at 15:16, Joe Darcy <joe.darcy at oracle.com> wrote:
>>>
>>>
>>> +     * @implSpec The default implementation first calls {@link
>>> +     * #getAnnotation(Class)} on the argument type. If the annotation
>>> +     * is directly or indirectly present, it is returned in an
>>> +     * one-element array. Otherwise, if the argument annotation type
>>> +     * is repeatable and an annotation of the container type is
>>> +     * directly or indirectly present, then the returned result is
>>> +     * equal to the result of calling the {@code value} method on the
>>> +     * container annotation.
> ...
>>> -    <T extends Annotation> T[] getAnnotationsByType(Class<T> 
>>> annotationClass);
>>> +    default <T extends Annotation> T[] 
>>> getAnnotationsByType(Class<T> annotationClass) {
>>>
>>
>> This is the wrong order. The precise lookup of an associated 
>> annotation is declared then inherited, quoting the javadoc for 
>> AnnotatedElement:
>
> Yes, and the root cause is an inconsistency in the @implSpec. The 
> first call to getAnnotation(Class) will tell you if an annotation is 
> _present_, which is not the same thing as "directly or indirectly 
> present". In fact, as a legacy method, getAnnotation(Class) will never 
> reveal an indirectly present annotation. The @implSpec should say "If 
> an annotation of type T is present, it is included in the returned 
> array. [If multiple annotations of type T are present because someone 
> made a Runtime*Annotations attribute with @Foo @Foo by hand, then the 
> first is chosen.]"
>
> There's a bigger problem: the word "Otherwise". The intent of 
> getAnnotationsByType(Class) is to expose the directly present 
> annotation (if any) _and_ indirectly present annotations as may be 
> found in a container annotation. This is Example 1.2-3 in 8misc.pdf, 
> where an @Foo and an @FooContainer are side by side on an element. 
> Returning a one-element array can't be right.

Second iteration for the default method aspects of getAnnotationsByType:

+     * @implSpec The default implementation first calls {@link
+     * #getDeclaredAnnotationsByType(Class)} on the argument type. If
+     * the returned array has size greater than zero, the array is
+     * returned. If the returned array has size zero and this {@code
+     * AnnotatedElement} is a class and the argument type is an
+     * inheritable annotation, and the superclass of this {@code
+     * AnnoatedElement} is non-null, then the result of {@code
+     * getAnnotationsByType(annotationClass)} on the superclass is
+     * returned. Otherwise, a zero-length array is returned.
+     *


>
>>> +     * @implSpec The default implementation first calls {@link
>>> +     * #getDeclaredAnnotation(Class)} on the argument type. If the
>>> +     * annotation is directly present, it is returned in an
>>> +     * one-element array. Otherwise, if the argument annotation type
>>> +     * is repeatable and an annotation of the container type is
>>> +     * directly present, then the returned result is equal to the
>>> +     * result of calling the {@code value} method on the container
>>> +     * annotation.
>>> +     *
>>>       * @param <T> the type of the annotation to query for and return
>>>       * if directly or indirectly present
>>>       * @param annotationClass the Class object corresponding to the
>>> @@ -277,7 +315,9 @@
>>>       * @throws NullPointerException if the given annotation class 
>>> is null
>>>       * @since 1.8
>>>       */
>>> -    <T extends Annotation> T[] 
>>> getDeclaredAnnotationsByType(Class<T> annotationClass);
>>> +    default <T extends Annotation> T[] 
>>> getDeclaredAnnotationsByType(Class<T> annotationClass) {
>>>
>>
>> This should work.
>
> In a similar fashion to above, the intent of 
> getDeclaredAnnotationsByType(Class) is to reveal all directly and 
> indirectly present annotations, not just one directly present annotation.

Second iteration for the default method aspects of 
getDeclaredAnnotationsByType:

+     * @implSpec The default implementation may call {@link
+     * #getDeclaredAnnotation(Class)} one or more times to find a
+     * directly present annotation and, if the annotation type is
+     * repeatable, to find a container annotation. If the annotation
+     * type is both directly and indirectly present, {@link
+     * getDeclaredAnnotations()} will get called to determine the
+     * order of the elements in the returned array. Alternatively,
+     * {@link getDeclaredAnnotations()} may be called a single time
+     * and the returned array examined for both directly and
+     * indirectly present annotations. The results of calling {@link
+     * getDeclaredAnnotations()} are assumed to be consistent with the
+     * results of calling {@code #getDeclaredAnnotation}

Thanks,

-Joe


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