Class AnnotationUtils


  • @API(status=INTERNAL,
         since="1.0")
    public final class AnnotationUtils
    extends java.lang.Object
    Collection of utilities for working with annotations.

    DISCLAIMER

    These utilities are intended solely for usage within the JUnit framework itself. Any usage by external parties is not supported. Use at your own risk!

    Some utilities are published via the maintained AnnotationSupport class.

    Since:
    1.0
    See Also:
    Annotation, AnnotatedElement, AnnotationSupport
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static java.util.concurrent.ConcurrentHashMap<java.lang.Class<? extends java.lang.annotation.Annotation>,​java.lang.Boolean> repeatableAnnotationContainerCache  
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private AnnotationUtils()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static java.util.List<java.lang.reflect.Field> findAnnotatedFields​(java.lang.Class<?> clazz, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, java.util.function.Predicate<java.lang.reflect.Field> predicate)  
      static java.util.List<java.lang.reflect.Field> findAnnotatedFields​(java.lang.Class<?> clazz, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, java.util.function.Predicate<java.lang.reflect.Field> predicate, ReflectionUtils.HierarchyTraversalMode traversalMode)
      Find all fields of the supplied class or interface that are annotated or meta-annotated with the specified annotationType and match the specified predicate.
      static java.util.List<java.lang.reflect.Method> findAnnotatedMethods​(java.lang.Class<?> clazz, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType, ReflectionUtils.HierarchyTraversalMode traversalMode)  
      static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findAnnotation​(java.lang.Class<?> clazz, java.lang.Class<A> annotationType, boolean searchEnclosingClasses)
      Find the first annotation of the specified type that is either directly present, meta-present, or indirectly present on the supplied class, optionally searching recursively through the enclosing class hierarchy if not found on the supplied class.
      static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findAnnotation​(java.lang.reflect.AnnotatedElement element, java.lang.Class<A> annotationType)  
      private static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findAnnotation​(java.lang.reflect.AnnotatedElement element, java.lang.Class<A> annotationType, boolean inherited, java.util.Set<java.lang.annotation.Annotation> visited)  
      static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findAnnotation​(java.lang.reflect.Parameter parameter, int index, java.lang.Class<A> annotationType)  
      static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findAnnotation​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element, java.lang.Class<A> annotationType)  
      private static <A extends java.lang.annotation.Annotation>
      java.util.Optional<A>
      findMetaAnnotation​(java.lang.Class<A> annotationType, java.lang.annotation.Annotation[] candidates, boolean inherited, java.util.Set<java.lang.annotation.Annotation> visited)  
      static java.util.List<java.lang.reflect.Field> findPublicAnnotatedFields​(java.lang.Class<?> clazz, java.lang.Class<?> fieldType, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)  
      private static <A extends java.lang.annotation.Annotation>
      void
      findRepeatableAnnotations​(java.lang.annotation.Annotation[] candidates, java.lang.Class<A> annotationType, java.lang.Class<? extends java.lang.annotation.Annotation> containerType, boolean inherited, java.util.Set<A> found, java.util.Set<java.lang.annotation.Annotation> visited)  
      static <A extends java.lang.annotation.Annotation>
      java.util.List<A>
      findRepeatableAnnotations​(java.lang.reflect.AnnotatedElement element, java.lang.Class<A> annotationType)  
      private static <A extends java.lang.annotation.Annotation>
      void
      findRepeatableAnnotations​(java.lang.reflect.AnnotatedElement element, java.lang.Class<A> annotationType, java.lang.Class<? extends java.lang.annotation.Annotation> containerType, boolean inherited, java.util.Set<A> found, java.util.Set<java.lang.annotation.Annotation> visited)  
      static <A extends java.lang.annotation.Annotation>
      java.util.List<A>
      findRepeatableAnnotations​(java.lang.reflect.Parameter parameter, int index, java.lang.Class<A> annotationType)  
      static <A extends java.lang.annotation.Annotation>
      java.util.List<A>
      findRepeatableAnnotations​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element, java.lang.Class<A> annotationType)  
      private static java.lang.reflect.AnnotatedElement getEffectiveAnnotatedParameter​(java.lang.reflect.Parameter parameter, int index)
      Due to a bug in javac on JDK versions prior to JDK 9, looking up annotations directly on a Parameter will fail for inner class constructors.
      static boolean isAnnotated​(java.lang.reflect.AnnotatedElement element, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
      Determine if an annotation of annotationType is either present or meta-present on the supplied element.
      static boolean isAnnotated​(java.lang.reflect.Parameter parameter, int index, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)  
      static boolean isAnnotated​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element, java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
      Determine if an annotation of annotationType is either present or meta-present on the supplied optional element.
      private static boolean isInJavaLangAnnotationPackage​(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)  
      private static boolean isRepeatableAnnotationContainer​(java.lang.Class<? extends java.lang.annotation.Annotation> candidateContainerType)
      Determine if the supplied annotation type is a container for a repeatable annotation.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • repeatableAnnotationContainerCache

        private static final java.util.concurrent.ConcurrentHashMap<java.lang.Class<? extends java.lang.annotation.Annotation>,​java.lang.Boolean> repeatableAnnotationContainerCache
    • Constructor Detail

      • AnnotationUtils

        private AnnotationUtils()
    • Method Detail

      • isAnnotated

        public static boolean isAnnotated​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element,
                                          java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
        Determine if an annotation of annotationType is either present or meta-present on the supplied optional element.
        See Also:
        findAnnotation(Optional, Class), AnnotationSupport.isAnnotated(Optional, Class)
      • isAnnotated

        public static boolean isAnnotated​(java.lang.reflect.Parameter parameter,
                                          int index,
                                          java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
        Since:
        1.8
        See Also:
        findAnnotation(Parameter, int, Class)
      • isAnnotated

        public static boolean isAnnotated​(java.lang.reflect.AnnotatedElement element,
                                          java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
        Determine if an annotation of annotationType is either present or meta-present on the supplied element.
        Parameters:
        element - the element on which to search for the annotation; may be null
        annotationType - the annotation type to search for; never null
        Returns:
        true if the annotation is present or meta-present
        See Also:
        findAnnotation(AnnotatedElement, Class), AnnotationSupport.isAnnotated(AnnotatedElement, Class)
      • findAnnotation

        public static <A extends java.lang.annotation.Annotation> java.util.Optional<A> findAnnotation​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element,
                                                                                                       java.lang.Class<A> annotationType)
        See Also:
        AnnotationSupport.findAnnotation(Optional, Class)
      • findAnnotation

        public static <A extends java.lang.annotation.Annotation> java.util.Optional<A> findAnnotation​(java.lang.reflect.Parameter parameter,
                                                                                                       int index,
                                                                                                       java.lang.Class<A> annotationType)
        Since:
        1.8
        See Also:
        findAnnotation(AnnotatedElement, Class)
      • findAnnotation

        private static <A extends java.lang.annotation.Annotation> java.util.Optional<A> findAnnotation​(java.lang.reflect.AnnotatedElement element,
                                                                                                        java.lang.Class<A> annotationType,
                                                                                                        boolean inherited,
                                                                                                        java.util.Set<java.lang.annotation.Annotation> visited)
      • findMetaAnnotation

        private static <A extends java.lang.annotation.Annotation> java.util.Optional<A> findMetaAnnotation​(java.lang.Class<A> annotationType,
                                                                                                            java.lang.annotation.Annotation[] candidates,
                                                                                                            boolean inherited,
                                                                                                            java.util.Set<java.lang.annotation.Annotation> visited)
      • findAnnotation

        public static <A extends java.lang.annotation.Annotation> java.util.Optional<A> findAnnotation​(java.lang.Class<?> clazz,
                                                                                                       java.lang.Class<A> annotationType,
                                                                                                       boolean searchEnclosingClasses)
        Find the first annotation of the specified type that is either directly present, meta-present, or indirectly present on the supplied class, optionally searching recursively through the enclosing class hierarchy if not found on the supplied class.

        The enclosing class hierarchy will only be searched above an inner class (i.e., a non-static member class).

        Type Parameters:
        A - the annotation type
        Parameters:
        clazz - the class on which to search for the annotation; may be null
        annotationType - the annotation type to search for; never null
        searchEnclosingClasses - whether the enclosing class hierarchy should be searched
        Returns:
        an Optional containing the annotation; never null but potentially empty
        Since:
        1.8
        See Also:
        findAnnotation(AnnotatedElement, Class)
      • findRepeatableAnnotations

        public static <A extends java.lang.annotation.Annotation> java.util.List<A> findRepeatableAnnotations​(java.util.Optional<? extends java.lang.reflect.AnnotatedElement> element,
                                                                                                              java.lang.Class<A> annotationType)
        Since:
        1.5
        See Also:
        AnnotationSupport.findRepeatableAnnotations(Optional, Class)
      • findRepeatableAnnotations

        public static <A extends java.lang.annotation.Annotation> java.util.List<A> findRepeatableAnnotations​(java.lang.reflect.Parameter parameter,
                                                                                                              int index,
                                                                                                              java.lang.Class<A> annotationType)
        Since:
        1.8
        See Also:
        findRepeatableAnnotations(AnnotatedElement, Class)
      • findRepeatableAnnotations

        private static <A extends java.lang.annotation.Annotation> void findRepeatableAnnotations​(java.lang.reflect.AnnotatedElement element,
                                                                                                  java.lang.Class<A> annotationType,
                                                                                                  java.lang.Class<? extends java.lang.annotation.Annotation> containerType,
                                                                                                  boolean inherited,
                                                                                                  java.util.Set<A> found,
                                                                                                  java.util.Set<java.lang.annotation.Annotation> visited)
      • findRepeatableAnnotations

        private static <A extends java.lang.annotation.Annotation> void findRepeatableAnnotations​(java.lang.annotation.Annotation[] candidates,
                                                                                                  java.lang.Class<A> annotationType,
                                                                                                  java.lang.Class<? extends java.lang.annotation.Annotation> containerType,
                                                                                                  boolean inherited,
                                                                                                  java.util.Set<A> found,
                                                                                                  java.util.Set<java.lang.annotation.Annotation> visited)
      • isRepeatableAnnotationContainer

        private static boolean isRepeatableAnnotationContainer​(java.lang.Class<? extends java.lang.annotation.Annotation> candidateContainerType)
        Determine if the supplied annotation type is a container for a repeatable annotation.
        Since:
        1.5
      • getEffectiveAnnotatedParameter

        private static java.lang.reflect.AnnotatedElement getEffectiveAnnotatedParameter​(java.lang.reflect.Parameter parameter,
                                                                                         int index)
        Due to a bug in javac on JDK versions prior to JDK 9, looking up annotations directly on a Parameter will fail for inner class constructors.

        Bug in javac on JDK versions prior to JDK 9

        The parameter annotations array in the compiled byte code for the user's class excludes an entry for the implicit enclosing instance parameter for an inner class constructor.

        Workaround

        This method provides a workaround for this off-by-one error by helping JUnit maintainers and extension authors to access annotations on the preceding Parameter object (i.e., index - 1). If the supplied index is zero in such situations this method will return null since the parameter for the implicit enclosing instance will never be annotated.

        WARNING

        The AnnotatedElement returned by this method should never be cast and treated as a Parameter since the metadata (e.g., Parameter.getName(), Parameter.getType(), etc.) will not match those for the declared parameter at the given index in an inner class constructor for code compiled with JDK 8.

        Returns:
        the supplied Parameter, or the effective Parameter if the aforementioned bug is detected, or null if the bug is detected and the supplied index is 0
        Since:
        1.8
      • findPublicAnnotatedFields

        public static java.util.List<java.lang.reflect.Field> findPublicAnnotatedFields​(java.lang.Class<?> clazz,
                                                                                        java.lang.Class<?> fieldType,
                                                                                        java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)
        See Also:
        AnnotationSupport.findPublicAnnotatedFields(Class, Class, Class)
      • findAnnotatedFields

        public static java.util.List<java.lang.reflect.Field> findAnnotatedFields​(java.lang.Class<?> clazz,
                                                                                  java.lang.Class<? extends java.lang.annotation.Annotation> annotationType,
                                                                                  java.util.function.Predicate<java.lang.reflect.Field> predicate,
                                                                                  ReflectionUtils.HierarchyTraversalMode traversalMode)
        Find all fields of the supplied class or interface that are annotated or meta-annotated with the specified annotationType and match the specified predicate.
        Parameters:
        clazz - the class or interface in which to find the fields; never null
        annotationType - the annotation type to search for; never null
        predicate - the field filter; never null
        traversalMode - the hierarchy traversal mode; never null
        Returns:
        the list of all such fields found; neither null nor mutable
      • isInJavaLangAnnotationPackage

        private static boolean isInJavaLangAnnotationPackage​(java.lang.Class<? extends java.lang.annotation.Annotation> annotationType)