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

Joel Borggrén-Franck joel.franck at oracle.com
Thu Oct 24 08:34:02 PDT 2013


Hi Joe,

I agree this would be nice to do, but see comments inline,

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.
> +     *
>      * @param <T> the type of the annotation to query for and return if present
>      * @param annotationClass the Class object corresponding to the
>      *        annotation type
> @@ -230,8 +241,10 @@
>      * @throws NullPointerException if the given annotation class is null
>      * @since 1.8
>      */
> -    <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:

	"• An annotation A is associated with an element E if either:
		• A is directly or indirectly present on E; or
		• No annotation of A 's type is directly or indirectly present on E, and E is a class, and A's type is inheritable, and A is associated with the superclass of E."

> 
> +     * @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.

> 
> +     * @implSpec The default implementation first performs a null check
> +     * and then loops over the results of {@link
> +     * getDeclaredAnnotations} returning the first annotation whose
> +     * annotation type matches the argument type.
> +     *
>      * @param <T> the type of the annotation to query for and return if directly present
>      * @param annotationClass the Class object corresponding to the
>      *        annotation type
> @@ -247,7 +265,18 @@
>      * @throws NullPointerException if the given annotation class is null
>      * @since 1.8
>      */
> -    <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass);
> +    default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
> 

Wouldn't this risk the same issues as when we turned isAnnotationPresent() into a default?

cheers
/Joel



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