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 31 /** 32 * Represents an annotated element of the program currently running in this 33 * VM. This interface allows annotations to be read reflectively. All 34 * annotations returned by methods in this interface are immutable and 35 * serializable. The arrays returned by methods of this interface may be modified 36 * by callers without affecting the arrays returned to other callers. 37 * 38 * <p>The {@link #getAnnotationsByType(Class)} and {@link 39 * #getDeclaredAnnotationsByType(Class)} methods support multiple 40 * annotations of the same type on an element. If the argument to 41 * either method is a repeatable annotation type (JLS 9.6), then the 42 * method will "look through" a container annotation (JLS 9.7), if 43 * present, and return any annotations inside the container. Container 44 * annotations may be generated at compile-time to wrap multiple 45 * annotations of the argument type. 46 * 47 * <p>The terms <em>directly present</em>, <em>indirectly present</em>, 48 * <em>present</em>, and <em>associated</em> are used throughout this 49 * interface to describe precisely which annotations are returned by 205 * @return annotations present on this element 206 * @since 1.5 207 */ 208 Annotation[] getAnnotations(); 209 210 /** 211 * Returns annotations that are <em>associated</em> with this element. 212 * 213 * If there are no annotations <em>associated</em> with this element, the return 214 * value is an array of length 0. 215 * 216 * The difference between this method and {@link #getAnnotation(Class)} 217 * is that this method detects if its argument is a <em>repeatable 218 * annotation type</em> (JLS 9.6), and if so, attempts to find one or 219 * more annotations of that type by "looking through" a container 220 * annotation. 221 * 222 * The caller of this method is free to modify the returned array; it will 223 * have no effect on the arrays returned to other callers. 224 * 225 * @param <T> the type of the annotation to query for and return if present 226 * @param annotationClass the Class object corresponding to the 227 * annotation type 228 * @return all this element's annotations for the specified annotation type if 229 * associated with this element, else an array of length zero 230 * @throws NullPointerException if the given annotation class is null 231 * @since 1.8 232 */ 233 <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass); 234 235 /** 236 * Returns this element's annotation for the specified type if 237 * such an annotation is <em>directly present</em>, else null. 238 * 239 * This method ignores inherited annotations. (Returns null if no 240 * annotations are directly present on this element.) 241 * 242 * @param <T> the type of the annotation to query for and return if directly present 243 * @param annotationClass the Class object corresponding to the 244 * annotation type 245 * @return this element's annotation for the specified annotation type if 246 * directly present on this element, else null 247 * @throws NullPointerException if the given annotation class is null 248 * @since 1.8 249 */ 250 <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass); 251 252 /** 253 * Returns this element's annotation(s) for the specified type if 254 * such annotations are either <em>directly present</em> or 255 * <em>indirectly present</em>. This method ignores inherited 256 * annotations. 257 * 258 * If there are no specified annotations directly or indirectly 259 * present on this element, the return value is an array of length 260 * 0. 261 * 262 * The difference between this method and {@link 263 * #getDeclaredAnnotation(Class)} is that this method detects if its 264 * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so, 265 * attempts to find one or more annotations of that type by "looking 266 * through" a container annotation if one is present. 267 * 268 * The caller of this method is free to modify the returned array; it will 269 * have no effect on the arrays returned to other callers. 270 * 271 * @param <T> the type of the annotation to query for and return 272 * if directly or indirectly present 273 * @param annotationClass the Class object corresponding to the 274 * annotation type 275 * @return all this element's annotations for the specified annotation type if 276 * directly or indirectly present on this element, else an array of length zero 277 * @throws NullPointerException if the given annotation class is null 278 * @since 1.8 279 */ 280 <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass); 281 282 /** 283 * Returns annotations that are <em>directly present</em> on this element. 284 * This method ignores inherited annotations. 285 * 286 * If there are no annotations <em>directly present</em> on this element, 287 * the return value is an array of length 0. 288 * 289 * The caller of this method is free to modify the returned array; it will 290 * have no effect on the arrays returned to other callers. 291 * 292 * @return annotations directly present on this element 293 * @since 1.5 294 */ 295 Annotation[] getDeclaredAnnotations(); 296 } | 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.Objects; 32 import sun.reflect.annotation.AnnotationSupport; 33 34 /** 35 * Represents an annotated element of the program currently running in this 36 * VM. This interface allows annotations to be read reflectively. All 37 * annotations returned by methods in this interface are immutable and 38 * serializable. The arrays returned by methods of this interface may be modified 39 * by callers without affecting the arrays returned to other callers. 40 * 41 * <p>The {@link #getAnnotationsByType(Class)} and {@link 42 * #getDeclaredAnnotationsByType(Class)} methods support multiple 43 * annotations of the same type on an element. If the argument to 44 * either method is a repeatable annotation type (JLS 9.6), then the 45 * method will "look through" a container annotation (JLS 9.7), if 46 * present, and return any annotations inside the container. Container 47 * annotations may be generated at compile-time to wrap multiple 48 * annotations of the argument type. 49 * 50 * <p>The terms <em>directly present</em>, <em>indirectly present</em>, 51 * <em>present</em>, and <em>associated</em> are used throughout this 52 * interface to describe precisely which annotations are returned by 208 * @return annotations present on this element 209 * @since 1.5 210 */ 211 Annotation[] getAnnotations(); 212 213 /** 214 * Returns annotations that are <em>associated</em> with this element. 215 * 216 * If there are no annotations <em>associated</em> with this element, the return 217 * value is an array of length 0. 218 * 219 * The difference between this method and {@link #getAnnotation(Class)} 220 * is that this method detects if its argument is a <em>repeatable 221 * annotation type</em> (JLS 9.6), and if so, attempts to find one or 222 * more annotations of that type by "looking through" a container 223 * annotation. 224 * 225 * The caller of this method is free to modify the returned array; it will 226 * have no effect on the arrays returned to other callers. 227 * 228 * @implSpec The default implementation first calls {@link 229 * #getDeclaredAnnotationsByType(Class)} on the argument type. If 230 * the returned array has size greater than zero, the array is 231 * returned. If the returned array has size zero and this {@code 232 * AnnotatedElement} is a class and the argument type is an 233 * inheritable annotation, and the superclass of this {@code 234 * AnnoatedElement} is non-null, then the result of {@code 235 * getAnnotationsByType(annotationClass)} on the superclass is 236 * returned. Otherwise, a zero-length array is returned. 237 * 238 * @param <T> the type of the annotation to query for and return if present 239 * @param annotationClass the Class object corresponding to the 240 * annotation type 241 * @return all this element's annotations for the specified annotation type if 242 * associated with this element, else an array of length zero 243 * @throws NullPointerException if the given annotation class is null 244 * @since 1.8 245 */ 246 default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 247 T[] result = getDeclaredAnnotationsByType(annotationClass); 248 if (result.length > 0) 249 return result; 250 else { 251 Class<?> thisClass = this.getClass(); 252 if (thisClass.equals(Class.class) && 253 annotationClass.getAnnotation(java.lang.annotation.Inherited.class) != null) { 254 Class<?> superClass = thisClass.getSuperclass(); 255 if (superClass != null) 256 return superClass.getAnnotationsByType(annotationClass); 257 } 258 assert result.length == 0; 259 return result; 260 } 261 } 262 263 /** 264 * Returns this element's annotation for the specified type if 265 * such an annotation is <em>directly present</em>, else null. 266 * 267 * This method ignores inherited annotations. (Returns null if no 268 * annotations are directly present on this element.) 269 * 270 * @implSpec The default implementation first performs a null check 271 * and then loops over the results of {@link 272 * getDeclaredAnnotations} returning the first annotation whose 273 * annotation type matches the argument type. 274 * 275 * @param <T> the type of the annotation to query for and return if directly present 276 * @param annotationClass the Class object corresponding to the 277 * annotation type 278 * @return this element's annotation for the specified annotation type if 279 * directly present on this element, else null 280 * @throws NullPointerException if the given annotation class is null 281 * @since 1.8 282 */ 283 default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 284 Objects.requireNonNull(annotationClass); 285 Annotation[] annotations = getDeclaredAnnotations(); // All directly-present annotations 286 for (Annotation annotation : annotations) { 287 if (annotationClass.equals(annotation.annotationType())) { 288 // More robust to do a cast at runtime instead of 289 // compile-time only. 290 return annotationClass.cast(annotation); 291 } 292 } 293 return null; 294 } 295 296 /** 297 * Returns this element's annotation(s) for the specified type if 298 * such annotations are either <em>directly present</em> or 299 * <em>indirectly present</em>. This method ignores inherited 300 * annotations. 301 * 302 * If there are no specified annotations directly or indirectly 303 * present on this element, the return value is an array of length 304 * 0. 305 * 306 * The difference between this method and {@link 307 * #getDeclaredAnnotation(Class)} is that this method detects if its 308 * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so, 309 * attempts to find one or more annotations of that type by "looking 310 * through" a container annotation if one is present. 311 * 312 * The caller of this method is free to modify the returned array; it will 313 * have no effect on the arrays returned to other callers. 314 * 315 * @implSpec The default implementation may call {@link 316 * #getDeclaredAnnotation(Class)} one or more times to find a 317 * directly present annotation and, if the annotation type is 318 * repeatable, to find a container annotation. If the annotation 319 * type is both directly and indirectly present, {@link 320 * getDeclaredAnnotations()} will get called to determine the 321 * order of the elements in the returned array. Alternatively, 322 * {@link getDeclaredAnnotations()} may be called a single time 323 * and the returned array examined for both directly and 324 * indirectly present annotations. The results of calling {@link 325 * getDeclaredAnnotations()} are assumed to be consistent with the 326 * results of calling {@code #getDeclaredAnnotation} 327 * 328 * @param <T> the type of the annotation to query for and return 329 * if directly or indirectly present 330 * @param annotationClass the Class object corresponding to the 331 * annotation type 332 * @return all this element's annotations for the specified annotation type if 333 * directly or indirectly present on this element, else an array of length zero 334 * @throws NullPointerException if the given annotation class is null 335 * @since 1.8 336 */ 337 default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 338 Objects.requireNonNull(annotationClass); 339 int resultSize = 0; 340 T directlyPresent = getDeclaredAnnotation(annotationClass); 341 @SuppressWarnings("unchecked") 342 T[] indirectlyPresent = (T[]) Array.newInstance(annotationClass, 0); 343 344 if (directlyPresent != null) { 345 resultSize++; 346 } 347 348 // If the annotation type is repeatable, look through a 349 // container if one is present 350 Repeatable repeatable = annotationClass.getAnnotation(Repeatable.class); 351 Class<? extends Annotation> containerType = null; 352 if (repeatable != null) { // T is a repeatable annotation type 353 containerType = repeatable.value(); 354 Annotation container = this.getDeclaredAnnotation(containerType); 355 if (container != null) { 356 indirectlyPresent = AnnotationSupport.getValueArray(container); 357 resultSize += indirectlyPresent.length; 358 } 359 } 360 361 if (resultSize == indirectlyPresent.length) { 362 assert resultSize == 0 || directlyPresent == null; 363 /* 364 * If resultSize is 0, indirectlyPresent is either 365 * assigned to the result of the initial Array.newInstance 366 * call or indirectlyPresent is assigned to a zero-lenght 367 * value array from an empty container annotation. In 368 * either case, a zero-length array is immutable and does 369 * not need to reallocated before being returned. 370 * 371 * If resultSize is nonzero, then indirectlyPresent points 372 * to the result calling a method on an annotation and 373 * annotations are required to implement a no sharing 374 * policy. Therefore, it is not required to copy the 375 * elements of indirectlyPresent into a new array of the 376 * same size. 377 */ 378 return indirectlyPresent; 379 } else { 380 assert resultSize > 0 && (directlyPresent != null || indirectlyPresent.length > 0); 381 @SuppressWarnings("unchecked") 382 T[] returnValue = (T[]) Array.newInstance(annotationClass, resultSize); 383 384 if (indirectlyPresent.length == 0) { 385 assert resultSize == 1; 386 returnValue[0] = directlyPresent; 387 } else { 388 assert directlyPresent != null && indirectlyPresent.length > 0; 389 // Determine whether the directly present annotation 390 // comes before or after the indirectly present ones. 391 392 int indirectOffset = 0; 393 394 for (Annotation a : getDeclaredAnnotations()) { 395 if (a.annotationType().equals(annotationClass)) { 396 indirectOffset = 1; 397 break; 398 } else if (a.annotationType().equals(containerType)) { 399 break; 400 } 401 } 402 403 for (int i = 0; i < resultSize; i++) { 404 returnValue[i + indirectOffset] = indirectlyPresent[i]; 405 } 406 407 returnValue[(indirectOffset == 1) ? 0 : resultSize - 1] = directlyPresent; 408 } 409 return returnValue; 410 } 411 } 412 413 414 /** 415 * Returns annotations that are <em>directly present</em> on this element. 416 * This method ignores inherited annotations. 417 * 418 * If there are no annotations <em>directly present</em> on this element, 419 * the return value is an array of length 0. 420 * 421 * The caller of this method is free to modify the returned array; it will 422 * have no effect on the arrays returned to other callers. 423 * 424 * @return annotations directly present on this element 425 * @since 1.5 426 */ 427 Annotation[] getDeclaredAnnotations(); 428 } |