org.springframework.core.annotation

## Interface MergedAnnotation<A extends Annotation>

- Type Parameters:
    `A` - the annotation type

      public interface MergedAnnotation<A extends Annotation>

  A single merged annotation returned from a `MergedAnnotations` collection. Presents a view onto an annotation where attribute values may have been "merged" from different source values.

  Attribute values may be accessed using the various `get` methods. For example, to access an `int` attribute the `getInt(String)` method would be used.

  Note that attribute values are not converted when accessed. For example, it is not possible to call `getString(String)` if the underlying attribute is an `int`. The only exception to this rule is `Class` and `Class[]` values which may be accessed as `String` and `String[]` respectively to prevent potential early class initialization.

  If necessary, a `MergedAnnotation` can be synthesized back into an actual `Annotation`.

  Since:
    5.2
  Author:
    Phillip Webb, Juergen Hoeller, Sam Brannen
  See Also:
    `MergedAnnotations`, `MergedAnnotationPredicates`

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Interface and Description
    --- | ---
    `static class` | `MergedAnnotation.Adapt` Adaptations that can be applied to attribute values when creating Maps or `AnnotationAttributes`.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static String` | `VALUE` The attribute name for annotations with a single element.

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `AnnotationAttributes` | `asAnnotationAttributes(MergedAnnotation.Adapt... adaptations)` Create a new mutable `AnnotationAttributes` instance from this merged annotation.
    `<T extends Map<String,Object>> T` | `asMap(Function<MergedAnnotation<?>,T> factory, MergedAnnotation.Adapt... adaptations)` Create a new `Map` instance of the given type that contains all the annotation attributes.
    `Map<String,Object>` | `asMap(MergedAnnotation.Adapt... adaptations)` Get an immutable `Map` that contains all the annotation attributes.
    `MergedAnnotation<A>` | `filterAttributes(Predicate<String> predicate)` Create a new view of the annotation with only attributes that match the given predicate.
    `MergedAnnotation<A>` | `filterDefaultValues()` Create a new view of the annotation with all attributes that have default values removed.
    `static <A extends Annotation> MergedAnnotation<A>` | `from(A annotation)` Create a new `MergedAnnotation` instance from the specified annotation.
    `static <A extends Annotation> MergedAnnotation<A>` | `from(Object source, A annotation)` Create a new `MergedAnnotation` instance from the specified annotation.
    `int` | `getAggregateIndex()` Get the index of the aggregate collection containing this annotation.
    `<T extends Annotation> MergedAnnotation<T>` | `getAnnotation(String attributeName, Class<T> type)` Get a required annotation attribute value from the annotation.
    `<T extends Annotation> MergedAnnotation<T>[]` | `getAnnotationArray(String attributeName, Class<T> type)` Get a required annotation array attribute value from the annotation.
    `boolean` | `getBoolean(String attributeName)` Get a required boolean attribute value from the annotation.
    `boolean[]` | `getBooleanArray(String attributeName)` Get a required boolean array attribute value from the annotation.
    `byte` | `getByte(String attributeName)` Get a required byte attribute value from the annotation.
    `byte[]` | `getByteArray(String attributeName)` Get a required byte array attribute value from the annotation.
    `char` | `getChar(String attributeName)` Get a required char attribute value from the annotation.
    `char[]` | `getCharArray(String attributeName)` Get a required char array attribute value from the annotation.
    `Class<?>` | `getClass(String attributeName)` Get a required class attribute value from the annotation.
    `Class<?>[]` | `getClassArray(String attributeName)` Get a required class array attribute value from the annotation.
    `Optional<Object>` | `getDefaultValue(String attributeName)` Get the default attribute value from the annotation as specified in the annotation declaration.
    `<T> Optional<T>` | `getDefaultValue(String attributeName, Class<T> type)` Get the default attribute value from the annotation as specified in the annotation declaration.
    `int` | `getDistance()` Get the distance of this annotation related to its use as a meta-annotation.
    `double` | `getDouble(String attributeName)` Get a required double attribute value from the annotation.
    `double[]` | `getDoubleArray(String attributeName)` Get a required double array attribute value from the annotation.
    `<E extends Enum<E>> E` | `getEnum(String attributeName, Class<E> type)` Get a required enum attribute value from the annotation.
    `<E extends Enum<E>> E[]` | `getEnumArray(String attributeName, Class<E> type)` Get a required enum array attribute value from the annotation.
    `float` | `getFloat(String attributeName)` Get a required float attribute value from the annotation.
    `float[]` | `getFloatArray(String attributeName)` Get a required float array attribute value from the annotation.
    `int` | `getInt(String attributeName)` Get a required int attribute value from the annotation.
    `int[]` | `getIntArray(String attributeName)` Get a required int array attribute value from the annotation.
    `long` | `getLong(String attributeName)` Get a required long attribute value from the annotation.
    `long[]` | `getLongArray(String attributeName)` Get a required long array attribute value from the annotation.
    `MergedAnnotation<?>` | `getMetaSource()` Get the source of the meta-annotation, or `null` if the annotation is not meta-present.
    `List<Class<? extends Annotation>>` | `getMetaTypes()` Get the complete list of annotation types within the annotation hierarchy from this annotation to the `root`.
    `MergedAnnotation<?>` | `getRoot()` Get the root annotation, i.e.
    `short` | `getShort(String attributeName)` Get a required short attribute value from the annotation.
    `short[]` | `getShortArray(String attributeName)` Get a required short array attribute value from the annotation.
    `Object` | `getSource()` Get the source that ultimately declared the root annotation, or `null` if the source is not known.
    `String` | `getString(String attributeName)` Get a required string attribute value from the annotation.
    `String[]` | `getStringArray(String attributeName)` Get a required string array attribute value from the annotation.
    `Class<A>` | `getType()` Get the `Class` reference for the actual annotation type.
    `Optional<Object>` | `getValue(String attributeName)` Get an optional attribute value from the annotation.
    `<T> Optional<T>` | `getValue(String attributeName, Class<T> type)` Get an optional attribute value from the annotation.
    `boolean` | `hasDefaultValue(String attributeName)` Determine if the specified attribute name has a default value when compared to the annotation declaration.
    `boolean` | `hasNonDefaultValue(String attributeName)` Determine if the specified attribute name has a non-default value when compared to the annotation declaration.
    `boolean` | `isDirectlyPresent()` Determine if the annotation is directly present on the source.
    `boolean` | `isMetaPresent()` Determine if the annotation is meta-present on the source.
    `boolean` | `isPresent()` Determine if the annotation is present on the source.
    `static <A extends Annotation> MergedAnnotation<A>` | `missing()` Create a `MergedAnnotation` that represents a missing annotation (i.e.
    `static <A extends Annotation> MergedAnnotation<A>` | `of(AnnotatedElement source, Class<A> annotationType, Map<String,?> attributes)` Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
    `static <A extends Annotation> MergedAnnotation<A>` | `of(Class<A> annotationType)` Create a new `MergedAnnotation` instance of the specified annotation type.
    `static <A extends Annotation> MergedAnnotation<A>` | `of(Class<A> annotationType, Map<String,?> attributes)` Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
    `static <A extends Annotation> MergedAnnotation<A>` | `of(ClassLoader classLoader, Object source, Class<A> annotationType, Map<String,?> attributes)` Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
    `A` | `synthesize()` Create a type-safe synthesized version of this merged annotation that can be used directly in code.
    `Optional<A>` | `synthesize(Predicate<? super MergedAnnotation<A>> condition)` Optionally create a type-safe synthesized version of this annotation based on a condition predicate.
    `MergedAnnotation<A>` | `withNonMergedAttributes()` Create a new view of the annotation that exposes non-merged attribute values.

- - ### Field Detail

    - #### VALUE

          static final String VALUE

      The attribute name for annotations with a single element.
      See Also:
        Constant Field Values

  - ### Method Detail

    - #### getType

          Class<A> getType()

      Get the `Class` reference for the actual annotation type.
      Returns:
        the annotation type

    - #### isPresent

          boolean isPresent()

      Determine if the annotation is present on the source. Considers directly present and meta-present annotations within the context of the `MergedAnnotations.SearchStrategy` used.
      Returns:
        `true` if the annotation is present

    - #### isDirectlyPresent

          boolean isDirectlyPresent()

      Determine if the annotation is directly present on the source.

      A directly present annotation is one that the user has explicitly declared and not one that is meta-present or `@Inherited`.

      Returns:
        `true` if the annotation is directly present

    - #### isMetaPresent

          boolean isMetaPresent()

      Determine if the annotation is meta-present on the source.

      A meta-present annotation is an annotation that the user hasn't explicitly declared, but has been used as a meta-annotation somewhere in the annotation hierarchy.

      Returns:
        `true` if the annotation is meta-present

    - #### getDistance

          int getDistance()

      Get the distance of this annotation related to its use as a meta-annotation.

      A directly declared annotation has a distance of `0`, a meta-annotation has a distance of `1`, a meta-annotation on a meta-annotation has a distance of `2`, etc. A missing annotation will always return a distance of `-1`.

      Returns:
        the annotation distance or `-1` if the annotation is missing

    - #### getAggregateIndex

          int getAggregateIndex()

      Get the index of the aggregate collection containing this annotation.

      Can be used to reorder a stream of annotations, for example, to give a higher priority to annotations declared on a superclass or interface. A missing annotation will always return an aggregate index of `-1`.

      Returns:
        the aggregate index (starting at `0`) or `-1` if the annotation is missing

    - #### getSource

          @Nullable
          Object getSource()

      Get the source that ultimately declared the root annotation, or `null` if the source is not known.

      If this merged annotation was created `from` an `AnnotatedElement` then this source will be an element of the same type. If the annotation was loaded without using reflection, the source can be of any type, but should have a sensible `toString()`. Meta-annotations will always return the same source as the `root`.

      Returns:
        the source, or `null`

    - #### getMetaSource

          @Nullable
          MergedAnnotation<?> getMetaSource()

      Get the source of the meta-annotation, or `null` if the annotation is not meta-present.

      The meta-source is the annotation that was meta-annotated with this annotation.

      Returns:
        the meta-annotation source or `null`
      See Also:
        `getRoot()`

    - #### getRoot

          MergedAnnotation<?> getRoot()

      Get the root annotation, i.e. the `distance` `0` annotation as directly declared on the source.
      Returns:
        the root annotation
      See Also:
        `getMetaSource()`

    - #### getMetaTypes

          List<Class<? extends Annotation>> getMetaTypes()

      Get the complete list of annotation types within the annotation hierarchy from this annotation to the `root`.

      Provides a useful way to uniquely identify a merged annotation instance.

      Returns:
        the meta types for the annotation
      See Also:
        `MergedAnnotationPredicates.unique(Function)`, `getRoot()`, `getMetaSource()`

    - #### hasNonDefaultValue

          boolean hasNonDefaultValue(String attributeName)

      Determine if the specified attribute name has a non-default value when compared to the annotation declaration.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        `true` if the attribute value is different from the default value

    - #### hasDefaultValue

          boolean hasDefaultValue(String attributeName)
                           throws NoSuchElementException

      Determine if the specified attribute name has a default value when compared to the annotation declaration.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        `true` if the attribute value is the same as the default value
      Throws:
        `NoSuchElementException`

    - #### getByte

          byte getByte(String attributeName)
                throws NoSuchElementException

      Get a required byte attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a byte
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getByteArray

          byte[] getByteArray(String attributeName)
                       throws NoSuchElementException

      Get a required byte array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a byte array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getBoolean

          boolean getBoolean(String attributeName)
                      throws NoSuchElementException

      Get a required boolean attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a boolean
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getBooleanArray

          boolean[] getBooleanArray(String attributeName)
                             throws NoSuchElementException

      Get a required boolean array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a boolean array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getChar

          char getChar(String attributeName)
                throws NoSuchElementException

      Get a required char attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a char
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getCharArray

          char[] getCharArray(String attributeName)
                       throws NoSuchElementException

      Get a required char array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a char array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getShort

          short getShort(String attributeName)
                  throws NoSuchElementException

      Get a required short attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a short
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getShortArray

          short[] getShortArray(String attributeName)
                         throws NoSuchElementException

      Get a required short array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a short array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getInt

          int getInt(String attributeName)
              throws NoSuchElementException

      Get a required int attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as an int
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getIntArray

          int[] getIntArray(String attributeName)
                     throws NoSuchElementException

      Get a required int array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as an int array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getLong

          long getLong(String attributeName)
                throws NoSuchElementException

      Get a required long attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a long
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getLongArray

          long[] getLongArray(String attributeName)
                       throws NoSuchElementException

      Get a required long array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a long array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getDouble

          double getDouble(String attributeName)
                    throws NoSuchElementException

      Get a required double attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a double
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getDoubleArray

          double[] getDoubleArray(String attributeName)
                           throws NoSuchElementException

      Get a required double array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a double array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getFloat

          float getFloat(String attributeName)
                  throws NoSuchElementException

      Get a required float attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a float
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getFloatArray

          float[] getFloatArray(String attributeName)
                         throws NoSuchElementException

      Get a required float array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a float array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getString

          String getString(String attributeName)
                    throws NoSuchElementException

      Get a required string attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a string
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getStringArray

          String[] getStringArray(String attributeName)
                           throws NoSuchElementException

      Get a required string array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a string array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getClass

          Class<?> getClass(String attributeName)
                     throws NoSuchElementException

      Get a required class attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a class
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getClassArray

          Class<?>[] getClassArray(String attributeName)
                            throws NoSuchElementException

      Get a required class array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        the value as a class array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getEnum

          <E extends Enum<E>> E getEnum(String attributeName,
                                        Class<E> type)
                                 throws NoSuchElementException

      Get a required enum attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
        `type` - the enum type
      Returns:
        the value as an enum
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getEnumArray

          <E extends Enum<E>> E[] getEnumArray(String attributeName,
                                               Class<E> type)
                                        throws NoSuchElementException

      Get a required enum array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
        `type` - the enum type
      Returns:
        the value as an enum array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getAnnotation

          <T extends Annotation> MergedAnnotation<T> getAnnotation(String attributeName,
                                                                   Class<T> type)
                                                            throws NoSuchElementException

      Get a required annotation attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
        `type` - the annotation type
      Returns:
        the value as a `MergedAnnotation`
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getAnnotationArray

          <T extends Annotation> MergedAnnotation<T>[] getAnnotationArray(String attributeName,
                                                                          Class<T> type)
                                                                   throws NoSuchElementException

      Get a required annotation array attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
        `type` - the annotation type
      Returns:
        the value as a `MergedAnnotation` array
      Throws:
        `NoSuchElementException` - if there is no matching attribute

    - #### getValue

          Optional<Object> getValue(String attributeName)

      Get an optional attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        an optional value or `Optional.empty()` if there is no matching attribute

    - #### getValue

          <T> Optional<T> getValue(String attributeName,
                                   Class<T> type)

      Get an optional attribute value from the annotation.
      Parameters:
        `attributeName` - the attribute name
        `type` - the attribute type. Must be compatible with the underlying attribute type or `Object.class`.
      Returns:
        an optional value or `Optional.empty()` if there is no matching attribute

    - #### getDefaultValue

          Optional<Object> getDefaultValue(String attributeName)

      Get the default attribute value from the annotation as specified in the annotation declaration.
      Parameters:
        `attributeName` - the attribute name
      Returns:
        an optional of the default value or `Optional.empty()` if there is no matching attribute or no defined default

    - #### getDefaultValue

          <T> Optional<T> getDefaultValue(String attributeName,
                                          Class<T> type)

      Get the default attribute value from the annotation as specified in the annotation declaration.
      Parameters:
        `attributeName` - the attribute name
        `type` - the attribute type. Must be compatible with the underlying attribute type or `Object.class`.
      Returns:
        an optional of the default value or `Optional.empty()` if there is no matching attribute or no defined default

    - #### filterDefaultValues

          MergedAnnotation<A> filterDefaultValues()

      Create a new view of the annotation with all attributes that have default values removed.
      Returns:
        a filtered view of the annotation without any attributes that have a default value
      See Also:
        `filterAttributes(Predicate)`

    - #### filterAttributes

          MergedAnnotation<A> filterAttributes(Predicate<String> predicate)

      Create a new view of the annotation with only attributes that match the given predicate.
      Parameters:
        `predicate` - a predicate used to filter attribute names
      Returns:
        a filtered view of the annotation
      See Also:
        `filterDefaultValues()`, `MergedAnnotationPredicates`

    - #### withNonMergedAttributes

          MergedAnnotation<A> withNonMergedAttributes()

      Create a new view of the annotation that exposes non-merged attribute values.

      Methods from this view will return attribute values with only alias mirroring rules applied. Aliases to `meta-source` attributes will not be applied.

      Returns:
        a non-merged view of the annotation

    - #### asAnnotationAttributes

          AnnotationAttributes asAnnotationAttributes(MergedAnnotation.Adapt... adaptations)

      Create a new mutable `AnnotationAttributes` instance from this merged annotation.

      The `adaptations` may be used to change the way that values are added.

      Parameters:
        `adaptations` - the adaptations that should be applied to the annotation values
      Returns:
        an immutable map containing the attributes and values

    - #### asMap

          Map<String,Object> asMap(MergedAnnotation.Adapt... adaptations)

      Get an immutable `Map` that contains all the annotation attributes.

      The `adaptations` may be used to change the way that values are added.

      Parameters:
        `adaptations` - the adaptations that should be applied to the annotation values
      Returns:
        an immutable map containing the attributes and values

    - #### asMap

          <T extends Map<String,Object>> T asMap(Function<MergedAnnotation<?>,T> factory,
                                                 MergedAnnotation.Adapt... adaptations)

      Create a new `Map` instance of the given type that contains all the annotation attributes.

      The `adaptations` may be used to change the way that values are added.

      Parameters:
        `factory` - a map factory
        `adaptations` - the adaptations that should be applied to the annotation values
      Returns:
        a map containing the attributes and values

    - #### synthesize

          A synthesize()
                throws NoSuchElementException

      Create a type-safe synthesized version of this merged annotation that can be used directly in code.

      The result is synthesized using a JDK `Proxy` and as a result may incur a computational cost when first invoked.

      If this merged annotation was created from a map of annotation attributes or default attribute values, those attributes will always be synthesized into an annotation instance.

      If this merged annotation was created from an annotation instance, that annotation will be returned unmodified if it is not synthesizable. An annotation is considered synthesizable if it has not already been synthesized and one of the following is true.

      - The annotation declares attributes annotated with `@AliasFor`.
      - The annotation is a composed annotation that relies on convention-based annotation attribute overrides in meta-annotations.
      - The annotation declares attributes that are annotations or arrays of annotations that are themselves synthesizable.
      Returns:
        a synthesized version of the annotation or the original annotation unmodified
      Throws:
        `NoSuchElementException` - on a missing annotation

    - #### synthesize

          Optional<A> synthesize(Predicate<? super MergedAnnotation<A>> condition)
                          throws NoSuchElementException

      Optionally create a type-safe synthesized version of this annotation based on a condition predicate.

      The result is synthesized using a JDK `Proxy` and as a result may incur a computational cost when first invoked.

      Consult the documentation for `synthesize()` for an explanation of what is considered synthesizable.

      Parameters:
        `condition` - the test to determine if the annotation can be synthesized
      Returns:
        an optional containing the synthesized version of the annotation or an empty optional if the condition doesn't match
      Throws:
        `NoSuchElementException` - on a missing annotation
      See Also:
        `MergedAnnotationPredicates`

    - #### missing

          static <A extends Annotation> MergedAnnotation<A> missing()

      Create a `MergedAnnotation` that represents a missing annotation (i.e. one that is not present).
      Returns:
        an instance representing a missing annotation

    - #### from

          static <A extends Annotation> MergedAnnotation<A> from(A annotation)

      Create a new `MergedAnnotation` instance from the specified annotation.
      Parameters:
        `annotation` - the annotation to include
      Returns:
        a `MergedAnnotation` instance containing the annotation

    - #### from

          static <A extends Annotation> MergedAnnotation<A> from(@Nullable
                                                                 Object source,
                                                                 A annotation)

      Create a new `MergedAnnotation` instance from the specified annotation.
      Parameters:
        `source` - the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations, and it will not be searched.
        `annotation` - the annotation to include
      Returns:
        a `MergedAnnotation` instance for the annotation

    - #### of

          static <A extends Annotation> MergedAnnotation<A> of(Class<A> annotationType)

      Create a new `MergedAnnotation` instance of the specified annotation type. The resulting annotation will not have any attribute values but may still be used to query default values.
      Parameters:
        `annotationType` - the annotation type
      Returns:
        a `MergedAnnotation` instance for the annotation

    - #### of

          static <A extends Annotation> MergedAnnotation<A> of(Class<A> annotationType,
                                                               @Nullable
                                                               Map<String,?> attributes)

      Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
      Parameters:
        `annotationType` - the annotation type
        `attributes` - the annotation attributes or `null` if just default values should be used
      Returns:
        a `MergedAnnotation` instance for the annotation and attributes
      See Also:
        `of(AnnotatedElement, Class, Map)`

    - #### of

          static <A extends Annotation> MergedAnnotation<A> of(@Nullable
                                                               AnnotatedElement source,
                                                               Class<A> annotationType,
                                                               @Nullable
                                                               Map<String,?> attributes)

      Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
      Parameters:
        `source` - the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations and it will not be searched.
        `annotationType` - the annotation type
        `attributes` - the annotation attributes or `null` if just default values should be used
      Returns:
        a `MergedAnnotation` instance for the annotation and attributes

    - #### of

          static <A extends Annotation> MergedAnnotation<A> of(@Nullable
                                                               ClassLoader classLoader,
                                                               @Nullable
                                                               Object source,
                                                               Class<A> annotationType,
                                                               @Nullable
                                                               Map<String,?> attributes)

      Create a new `MergedAnnotation` instance of the specified annotation type with attribute values supplied by a map.
      Parameters:
        `classLoader` - the class loader used to resolve class attributes
        `source` - the source for the annotation. This source is used only for information and logging. It does not need to actually contain the specified annotations and it will not be searched.
        `annotationType` - the annotation type
        `attributes` - the annotation attributes or `null` if just default values should be used
      Returns:
        a `MergedAnnotation` instance for the annotation and attributes