jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java
changeset 25859 3317bb8137f4
parent 22080 18a23ba7dd38
child 44846 b3f9f5bf40b2
equal deleted inserted replaced
25858:836adbf7a2cd 25859:3317bb8137f4
       
     1 /*
       
     2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.lang.reflect;
       
    27 
       
    28 import java.lang.annotation.Annotation;
       
    29 import java.lang.annotation.AnnotationFormatError;
       
    30 import java.lang.annotation.Repeatable;
       
    31 import java.util.Arrays;
       
    32 import java.util.LinkedHashMap;
       
    33 import java.util.Map;
       
    34 import java.util.Objects;
       
    35 import java.util.function.Function;
       
    36 import java.util.stream.Collectors;
       
    37 import sun.reflect.annotation.AnnotationSupport;
       
    38 import sun.reflect.annotation.AnnotationType;
       
    39 
       
    40 /**
       
    41  * Represents an annotated element of the program currently running in this
       
    42  * VM.  This interface allows annotations to be read reflectively.  All
       
    43  * annotations returned by methods in this interface are immutable and
       
    44  * serializable. The arrays returned by methods of this interface may be modified
       
    45  * by callers without affecting the arrays returned to other callers.
       
    46  *
       
    47  * <p>The {@link #getAnnotationsByType(Class)} and {@link
       
    48  * #getDeclaredAnnotationsByType(Class)} methods support multiple
       
    49  * annotations of the same type on an element. If the argument to
       
    50  * either method is a repeatable annotation type (JLS 9.6), then the
       
    51  * method will "look through" a container annotation (JLS 9.7), if
       
    52  * present, and return any annotations inside the container. Container
       
    53  * annotations may be generated at compile-time to wrap multiple
       
    54  * annotations of the argument type.
       
    55  *
       
    56  * <p>The terms <em>directly present</em>, <em>indirectly present</em>,
       
    57  * <em>present</em>, and <em>associated</em> are used throughout this
       
    58  * interface to describe precisely which annotations are returned by
       
    59  * methods:
       
    60  *
       
    61  * <ul>
       
    62  *
       
    63  * <li> An annotation <i>A</i> is <em>directly present</em> on an
       
    64  * element <i>E</i> if <i>E</i> has a {@code
       
    65  * RuntimeVisibleAnnotations} or {@code
       
    66  * RuntimeVisibleParameterAnnotations} or {@code
       
    67  * RuntimeVisibleTypeAnnotations} attribute, and the attribute
       
    68  * contains <i>A</i>.
       
    69  *
       
    70  * <li>An annotation <i>A</i> is <em>indirectly present</em> on an
       
    71  * element <i>E</i> if <i>E</i> has a {@code RuntimeVisibleAnnotations} or
       
    72  * {@code RuntimeVisibleParameterAnnotations} or {@code RuntimeVisibleTypeAnnotations}
       
    73  * attribute, and <i>A</i> 's type is repeatable, and the attribute contains
       
    74  * exactly one annotation whose value element contains <i>A</i> and whose
       
    75  * type is the containing annotation type of <i>A</i> 's type.
       
    76  *
       
    77  * <li>An annotation <i>A</i> is present on an element <i>E</i> if either:
       
    78  *
       
    79  * <ul>
       
    80  *
       
    81  * <li><i>A</i> is directly present on <i>E</i>; or
       
    82  *
       
    83  * <li>No annotation of <i>A</i> 's type is directly present on
       
    84  * <i>E</i>, and <i>E</i> is a class, and <i>A</i> 's type is
       
    85  * inheritable, and <i>A</i> is present on the superclass of <i>E</i>.
       
    86  *
       
    87  * </ul>
       
    88  *
       
    89  * <li>An annotation <i>A</i> is <em>associated</em> with an element <i>E</i>
       
    90  * if either:
       
    91  *
       
    92  * <ul>
       
    93  *
       
    94  * <li><i>A</i> is directly or indirectly present on <i>E</i>; or
       
    95  *
       
    96  * <li>No annotation of <i>A</i> 's type is directly or indirectly
       
    97  * present on <i>E</i>, and <i>E</i> is a class, and <i>A</i>'s type
       
    98  * is inheritable, and <i>A</i> is associated with the superclass of
       
    99  * <i>E</i>.
       
   100  *
       
   101  * </ul>
       
   102  *
       
   103  * </ul>
       
   104  *
       
   105  * <p>The table below summarizes which kind of annotation presence
       
   106  * different methods in this interface examine.
       
   107  *
       
   108  * <table border>
       
   109  * <caption>Overview of kind of presence detected by different AnnotatedElement methods</caption>
       
   110  * <tr><th colspan=2></th><th colspan=4>Kind of Presence</th>
       
   111  * <tr><th colspan=2>Method</th><th>Directly Present</th><th>Indirectly Present</th><th>Present</th><th>Associated</th>
       
   112  * <tr><td align=right>{@code T}</td><td>{@link #getAnnotation(Class) getAnnotation(Class&lt;T&gt;)}
       
   113  * <td></td><td></td><td>X</td><td></td>
       
   114  * </tr>
       
   115  * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getAnnotations getAnnotations()}
       
   116  * <td></td><td></td><td>X</td><td></td>
       
   117  * </tr>
       
   118  * <tr><td align=right>{@code T[]}</td><td>{@link #getAnnotationsByType(Class) getAnnotationsByType(Class&lt;T&gt;)}
       
   119  * <td></td><td></td><td></td><td>X</td>
       
   120  * </tr>
       
   121  * <tr><td align=right>{@code T}</td><td>{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class&lt;T&gt;)}
       
   122  * <td>X</td><td></td><td></td><td></td>
       
   123  * </tr>
       
   124  * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getDeclaredAnnotations getDeclaredAnnotations()}
       
   125  * <td>X</td><td></td><td></td><td></td>
       
   126  * </tr>
       
   127  * <tr><td align=right>{@code T[]}</td><td>{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class&lt;T&gt;)}
       
   128  * <td>X</td><td>X</td><td></td><td></td>
       
   129  * </tr>
       
   130  * </table>
       
   131  *
       
   132  * <p>For an invocation of {@code get[Declared]AnnotationsByType( Class <
       
   133  * T >)}, the order of annotations which are directly or indirectly
       
   134  * present on an element <i>E</i> is computed as if indirectly present
       
   135  * annotations on <i>E</i> are directly present on <i>E</i> in place
       
   136  * of their container annotation, in the order in which they appear in
       
   137  * the value element of the container annotation.
       
   138  *
       
   139  * <p>There are several compatibility concerns to keep in mind if an
       
   140  * annotation type <i>T</i> is originally <em>not</em> repeatable and
       
   141  * later modified to be repeatable.
       
   142  *
       
   143  * The containing annotation type for <i>T</i> is <i>TC</i>.
       
   144  *
       
   145  * <ul>
       
   146  *
       
   147  * <li>Modifying <i>T</i> to be repeatable is source and binary
       
   148  * compatible with existing uses of <i>T</i> and with existing uses
       
   149  * of <i>TC</i>.
       
   150  *
       
   151  * That is, for source compatibility, source code with annotations of
       
   152  * type <i>T</i> or of type <i>TC</i> will still compile. For binary
       
   153  * compatibility, class files with annotations of type <i>T</i> or of
       
   154  * type <i>TC</i> (or with other kinds of uses of type <i>T</i> or of
       
   155  * type <i>TC</i>) will link against the modified version of <i>T</i>
       
   156  * if they linked against the earlier version.
       
   157  *
       
   158  * (An annotation type <i>TC</i> may informally serve as an acting
       
   159  * containing annotation type before <i>T</i> is modified to be
       
   160  * formally repeatable. Alternatively, when <i>T</i> is made
       
   161  * repeatable, <i>TC</i> can be introduced as a new type.)
       
   162  *
       
   163  * <li>If an annotation type <i>TC</i> is present on an element, and
       
   164  * <i>T</i> is modified to be repeatable with <i>TC</i> as its
       
   165  * containing annotation type then:
       
   166  *
       
   167  * <ul>
       
   168  *
       
   169  * <li>The change to <i>T</i> is behaviorally compatible with respect
       
   170  * to the {@code get[Declared]Annotation(Class<T>)} (called with an
       
   171  * argument of <i>T</i> or <i>TC</i>) and {@code
       
   172  * get[Declared]Annotations()} methods because the results of the
       
   173  * methods will not change due to <i>TC</i> becoming the containing
       
   174  * annotation type for <i>T</i>.
       
   175  *
       
   176  * <li>The change to <i>T</i> changes the results of the {@code
       
   177  * get[Declared]AnnotationsByType(Class<T>)} methods called with an
       
   178  * argument of <i>T</i>, because those methods will now recognize an
       
   179  * annotation of type <i>TC</i> as a container annotation for <i>T</i>
       
   180  * and will "look through" it to expose annotations of type <i>T</i>.
       
   181  *
       
   182  * </ul>
       
   183  *
       
   184  * <li>If an annotation of type <i>T</i> is present on an
       
   185  * element and <i>T</i> is made repeatable and more annotations of
       
   186  * type <i>T</i> are added to the element:
       
   187  *
       
   188  * <ul>
       
   189  *
       
   190  * <li> The addition of the annotations of type <i>T</i> is both
       
   191  * source compatible and binary compatible.
       
   192  *
       
   193  * <li>The addition of the annotations of type <i>T</i> changes the results
       
   194  * of the {@code get[Declared]Annotation(Class<T>)} methods and {@code
       
   195  * get[Declared]Annotations()} methods, because those methods will now
       
   196  * only see a container annotation on the element and not see an
       
   197  * annotation of type <i>T</i>.
       
   198  *
       
   199  * <li>The addition of the annotations of type <i>T</i> changes the
       
   200  * results of the {@code get[Declared]AnnotationsByType(Class<T>)}
       
   201  * methods, because their results will expose the additional
       
   202  * annotations of type <i>T</i> whereas previously they exposed only a
       
   203  * single annotation of type <i>T</i>.
       
   204  *
       
   205  * </ul>
       
   206  *
       
   207  * </ul>
       
   208  *
       
   209  * <p>If an annotation returned by a method in this interface contains
       
   210  * (directly or indirectly) a {@link Class}-valued member referring to
       
   211  * a class that is not accessible in this VM, attempting to read the class
       
   212  * by calling the relevant Class-returning method on the returned annotation
       
   213  * will result in a {@link TypeNotPresentException}.
       
   214  *
       
   215  * <p>Similarly, attempting to read an enum-valued member will result in
       
   216  * a {@link EnumConstantNotPresentException} if the enum constant in the
       
   217  * annotation is no longer present in the enum type.
       
   218  *
       
   219  * <p>If an annotation type <i>T</i> is (meta-)annotated with an
       
   220  * {@code @Repeatable} annotation whose value element indicates a type
       
   221  * <i>TC</i>, but <i>TC</i> does not declare a {@code value()} method
       
   222  * with a return type of <i>T</i>{@code []}, then an exception of type
       
   223  * {@link java.lang.annotation.AnnotationFormatError} is thrown.
       
   224  *
       
   225  * <p>Finally, attempting to read a member whose definition has evolved
       
   226  * incompatibly will result in a {@link
       
   227  * java.lang.annotation.AnnotationTypeMismatchException} or an
       
   228  * {@link java.lang.annotation.IncompleteAnnotationException}.
       
   229  *
       
   230  * @see java.lang.EnumConstantNotPresentException
       
   231  * @see java.lang.TypeNotPresentException
       
   232  * @see AnnotationFormatError
       
   233  * @see java.lang.annotation.AnnotationTypeMismatchException
       
   234  * @see java.lang.annotation.IncompleteAnnotationException
       
   235  * @since 1.5
       
   236  * @author Josh Bloch
       
   237  */
       
   238 public interface AnnotatedElement {
       
   239     /**
       
   240      * Returns true if an annotation for the specified type
       
   241      * is <em>present</em> on this element, else false.  This method
       
   242      * is designed primarily for convenient access to marker annotations.
       
   243      *
       
   244      * <p>The truth value returned by this method is equivalent to:
       
   245      * {@code getAnnotation(annotationClass) != null}
       
   246      *
       
   247      * <p>The body of the default method is specified to be the code
       
   248      * above.
       
   249      *
       
   250      * @param annotationClass the Class object corresponding to the
       
   251      *        annotation type
       
   252      * @return true if an annotation for the specified annotation
       
   253      *     type is present on this element, else false
       
   254      * @throws NullPointerException if the given annotation class is null
       
   255      * @since 1.5
       
   256      */
       
   257     default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
       
   258         return getAnnotation(annotationClass) != null;
       
   259     }
       
   260 
       
   261    /**
       
   262      * Returns this element's annotation for the specified type if
       
   263      * such an annotation is <em>present</em>, else null.
       
   264      *
       
   265      * @param <T> the type of the annotation to query for and return if present
       
   266      * @param annotationClass the Class object corresponding to the
       
   267      *        annotation type
       
   268      * @return this element's annotation for the specified annotation type if
       
   269      *     present on this element, else null
       
   270      * @throws NullPointerException if the given annotation class is null
       
   271      * @since 1.5
       
   272      */
       
   273     <T extends Annotation> T getAnnotation(Class<T> annotationClass);
       
   274 
       
   275     /**
       
   276      * Returns annotations that are <em>present</em> on this element.
       
   277      *
       
   278      * If there are no annotations <em>present</em> on this element, the return
       
   279      * value is an array of length 0.
       
   280      *
       
   281      * The caller of this method is free to modify the returned array; it will
       
   282      * have no effect on the arrays returned to other callers.
       
   283      *
       
   284      * @return annotations present on this element
       
   285      * @since 1.5
       
   286      */
       
   287     Annotation[] getAnnotations();
       
   288 
       
   289     /**
       
   290      * Returns annotations that are <em>associated</em> with this element.
       
   291      *
       
   292      * If there are no annotations <em>associated</em> with this element, the return
       
   293      * value is an array of length 0.
       
   294      *
       
   295      * The difference between this method and {@link #getAnnotation(Class)}
       
   296      * is that this method detects if its argument is a <em>repeatable
       
   297      * annotation type</em> (JLS 9.6), and if so, attempts to find one or
       
   298      * more annotations of that type by "looking through" a container
       
   299      * annotation.
       
   300      *
       
   301      * The caller of this method is free to modify the returned array; it will
       
   302      * have no effect on the arrays returned to other callers.
       
   303      *
       
   304      * @implSpec The default implementation first calls {@link
       
   305      * #getDeclaredAnnotationsByType(Class)} passing {@code
       
   306      * annotationClass} as the argument. If the returned array has
       
   307      * length greater than zero, the array is returned. If the returned
       
   308      * array is zero-length and this {@code AnnotatedElement} is a
       
   309      * class and the argument type is an inheritable annotation type,
       
   310      * and the superclass of this {@code AnnotatedElement} is non-null,
       
   311      * then the returned result is the result of calling {@link
       
   312      * #getAnnotationsByType(Class)} on the superclass with {@code
       
   313      * annotationClass} as the argument. Otherwise, a zero-length
       
   314      * array is returned.
       
   315      *
       
   316      * @param <T> the type of the annotation to query for and return if present
       
   317      * @param annotationClass the Class object corresponding to the
       
   318      *        annotation type
       
   319      * @return all this element's annotations for the specified annotation type if
       
   320      *     associated with this element, else an array of length zero
       
   321      * @throws NullPointerException if the given annotation class is null
       
   322      * @since 1.8
       
   323      */
       
   324     default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
       
   325          /*
       
   326           * Definition of associated: directly or indirectly present OR
       
   327           * neither directly nor indirectly present AND the element is
       
   328           * a Class, the annotation type is inheritable, and the
       
   329           * annotation type is associated with the superclass of the
       
   330           * element.
       
   331           */
       
   332          T[] result = getDeclaredAnnotationsByType(annotationClass);
       
   333 
       
   334          if (result.length == 0 && // Neither directly nor indirectly present
       
   335              this instanceof Class && // the element is a class
       
   336              AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
       
   337              Class<?> superClass = ((Class<?>) this).getSuperclass();
       
   338              if (superClass != null) {
       
   339                  // Determine if the annotation is associated with the
       
   340                  // superclass
       
   341                  result = superClass.getAnnotationsByType(annotationClass);
       
   342              }
       
   343          }
       
   344 
       
   345          return result;
       
   346      }
       
   347 
       
   348     /**
       
   349      * Returns this element's annotation for the specified type if
       
   350      * such an annotation is <em>directly present</em>, else null.
       
   351      *
       
   352      * This method ignores inherited annotations. (Returns null if no
       
   353      * annotations are directly present on this element.)
       
   354      *
       
   355      * @implSpec The default implementation first performs a null check
       
   356      * and then loops over the results of {@link
       
   357      * #getDeclaredAnnotations} returning the first annotation whose
       
   358      * annotation type matches the argument type.
       
   359      *
       
   360      * @param <T> the type of the annotation to query for and return if directly present
       
   361      * @param annotationClass the Class object corresponding to the
       
   362      *        annotation type
       
   363      * @return this element's annotation for the specified annotation type if
       
   364      *     directly present on this element, else null
       
   365      * @throws NullPointerException if the given annotation class is null
       
   366      * @since 1.8
       
   367      */
       
   368     default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
       
   369          Objects.requireNonNull(annotationClass);
       
   370          // Loop over all directly-present annotations looking for a matching one
       
   371          for (Annotation annotation : getDeclaredAnnotations()) {
       
   372              if (annotationClass.equals(annotation.annotationType())) {
       
   373                  // More robust to do a dynamic cast at runtime instead
       
   374                  // of compile-time only.
       
   375                  return annotationClass.cast(annotation);
       
   376              }
       
   377          }
       
   378          return null;
       
   379      }
       
   380 
       
   381     /**
       
   382      * Returns this element's annotation(s) for the specified type if
       
   383      * such annotations are either <em>directly present</em> or
       
   384      * <em>indirectly present</em>. This method ignores inherited
       
   385      * annotations.
       
   386      *
       
   387      * If there are no specified annotations directly or indirectly
       
   388      * present on this element, the return value is an array of length
       
   389      * 0.
       
   390      *
       
   391      * The difference between this method and {@link
       
   392      * #getDeclaredAnnotation(Class)} is that this method detects if its
       
   393      * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so,
       
   394      * attempts to find one or more annotations of that type by "looking
       
   395      * through" a container annotation if one is present.
       
   396      *
       
   397      * The caller of this method is free to modify the returned array; it will
       
   398      * have no effect on the arrays returned to other callers.
       
   399      *
       
   400      * @implSpec The default implementation may call {@link
       
   401      * #getDeclaredAnnotation(Class)} one or more times to find a
       
   402      * directly present annotation and, if the annotation type is
       
   403      * repeatable, to find a container annotation. If annotations of
       
   404      * the annotation type {@code annotationClass} are found to be both
       
   405      * directly and indirectly present, then {@link
       
   406      * #getDeclaredAnnotations()} will get called to determine the
       
   407      * order of the elements in the returned array.
       
   408      *
       
   409      * <p>Alternatively, the default implementation may call {@link
       
   410      * #getDeclaredAnnotations()} a single time and the returned array
       
   411      * examined for both directly and indirectly present
       
   412      * annotations. The results of calling {@link
       
   413      * #getDeclaredAnnotations()} are assumed to be consistent with the
       
   414      * results of calling {@link #getDeclaredAnnotation(Class)}.
       
   415      *
       
   416      * @param <T> the type of the annotation to query for and return
       
   417      * if directly or indirectly present
       
   418      * @param annotationClass the Class object corresponding to the
       
   419      *        annotation type
       
   420      * @return all this element's annotations for the specified annotation type if
       
   421      *     directly or indirectly present on this element, else an array of length zero
       
   422      * @throws NullPointerException if the given annotation class is null
       
   423      * @since 1.8
       
   424      */
       
   425     default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
       
   426         Objects.requireNonNull(annotationClass);
       
   427         return AnnotationSupport.
       
   428             getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
       
   429                                             collect(Collectors.toMap(Annotation::annotationType,
       
   430                                                                      Function.identity(),
       
   431                                                                      ((first,second) -> first),
       
   432                                                                      LinkedHashMap::new)),
       
   433                                             annotationClass);
       
   434     }
       
   435 
       
   436     /**
       
   437      * Returns annotations that are <em>directly present</em> on this element.
       
   438      * This method ignores inherited annotations.
       
   439      *
       
   440      * If there are no annotations <em>directly present</em> on this element,
       
   441      * the return value is an array of length 0.
       
   442      *
       
   443      * The caller of this method is free to modify the returned array; it will
       
   444      * have no effect on the arrays returned to other callers.
       
   445      *
       
   446      * @return annotations directly present on this element
       
   447      * @since 1.5
       
   448      */
       
   449     Annotation[] getDeclaredAnnotations();
       
   450 }