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