|
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<T>)} |
|
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<T>)} |
|
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<T>)} |
|
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<T>)} |
|
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 } |