Class AnnotationInfo<T extends Annotation>

java.lang.Object
org.apache.juneau.commons.reflect.AnnotationInfo<T>
Type Parameters:
T - The annotation type.

public class AnnotationInfo<T extends Annotation> extends Object
Encapsulates information about an annotation instance and the element it's declared on.

This class provides a convenient wrapper around Java annotations that allows you to:

  • Access annotation values in a type-safe manner
  • Query annotation properties without reflection boilerplate
  • Track where the annotation was found (class, method, field, etc.)
  • Sort annotations by precedence using ranks
Example:

// Get annotation info from a class ClassInfo ci = ClassInfo.of(MyClass.class); Optional<AnnotationInfo<MyAnnotation>> ai = ci.getAnnotations(MyAnnotation.class).findFirst(); // Access annotation values ai.ifPresent(x -> { String value = x.getValue(String.class, "value").orElse("default"); int priority = x.getInt("priority").orElse(0); });

See Also:
  • Method Details

    • of

      public static <A extends Annotation> AnnotationInfo<A> of(Annotatable on, A value)
      Creates a new annotation info object.
      Example:

      // Create annotation info for a class annotation ClassInfo ci = ClassInfo.of(MyClass.class); MyAnnotation annotation = ci.inner().getAnnotation(MyAnnotation.class); AnnotationInfo<MyAnnotation> ai = AnnotationInfo.of(ci, annotation);

      Type Parameters:
      A - The annotation type.
      Parameters:
      on - The annotatable object where the annotation was found (class, method, field, constructor, parameter, or package).
      value - The annotation instance. Must not be null.
      Returns:
      A new AnnotationInfo object wrapping the annotation.
    • annotationType

      public Class<? extends Annotation> annotationType()
      Returns the annotation type of this annotation.

      Same as calling Annotation.annotationType().

      Example:

      AnnotationInfo<Deprecated> ai = ClassInfo.of(MyClass.class).getAnnotation(Deprecated.class); Class<? extends Annotation> type = ai.annotationType(); // Returns Deprecated.class

      Returns:
      The annotation type of this annotation.
      See Also:
    • cast

      public <A extends Annotation> AnnotationInfo<A> cast(Class<A> type)
      Casts this annotation info to a specific annotation type.

      This is useful when you have an AnnotationInfo<?> and need to narrow it to a specific type.

      Example:

      AnnotationInfo<?> ai = ...; // Safe cast AnnotationInfo<MyAnnotation> myAi = ai.cast(MyAnnotation.class); if (myAi != null) { // Use strongly-typed annotation info }

      Type Parameters:
      A - The annotation type to cast to.
      Parameters:
      type - The annotation type to cast to.
      Returns:
      This annotation info cast to the specified type, or null if the annotation is not of the specified type.
    • equals

      public boolean equals(Object o)
      Returns true if the specified object represents an annotation that is logically equivalent to this one.

      Same as calling Annotation.equals(Object) on the wrapped annotation.

      Two annotations are considered equal if:

      • They are of the same annotation type
      • All their corresponding member values are equal
      Overrides:
      equals in class Object
      Parameters:
      o - The reference object with which to compare.
      Returns:
      true if the specified object is equal to this annotation.
      See Also:
    • getBoolean

      public Optional<Boolean> getBoolean(String methodName)
      Returns the value of the specified method on this annotation as a boolean.
      Example:

      // For annotation: @MyAnnotation(enabled=true) AnnotationInfo<MyAnnotation> ai = ...; boolean enabled = ai.getBoolean("enabled").orElse(false); // Returns true

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as a boolean, or empty if not found or not a boolean type.
    • getClassArray

      public Optional<Class<?>[]> getClassArray(String methodName)
      Returns the value of the specified method on this annotation as a class array.

      For type-safe access to an array of classes of a specific supertype, use getClassArray(String, Class).

      Example:

      // For annotation: @MyAnnotation(types={String.class, Integer.class}) AnnotationInfo<MyAnnotation> ai = ...; Class<?>[] types = ai.getClassArray("types").orElse(new Class[0]); // Returns [String.class, Integer.class]

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the class array value, or empty if not found or not a Class[] type.
    • getClassArray

      public <T> Optional<Class<? extends T>[]> getClassArray(String methodName, Class<T> type)
      Returns the value of the specified method on this annotation as a class array of a specific type.
      Example:

      // Get an array of serializer classes from an annotation Optional<Class<? extends Serializer>[]> serializerClasses = annotationInfo.getClassArray("serializers", Serializer.class);

      Type Parameters:
      T - The expected supertype of the classes.
      Parameters:
      methodName - The method name.
      type - The expected supertype of the class values.
      Returns:
      An optional containing the value of the specified method cast to the expected type, or empty if not found, not a class array, or any element is not assignable to the expected type.
    • getClassValue

      public Optional<Class<?>> getClassValue(String methodName)
      Returns the value of the specified method on this annotation as a class.

      For type-safe access to a class of a specific supertype, use getClassValue(String, Class).

      Example:

      // For annotation: @MyAnnotation(type=String.class) AnnotationInfo<MyAnnotation> ai = ...; Class<?> type = ai.getClassValue("type").orElse(null); // Returns String.class

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the class value, or empty if not found or not a Class type.
    • getClassValue

      public <T> Optional<Class<? extends T>> getClassValue(String methodName, Class<T> type)
      Returns the value of the specified method on this annotation as a class of a specific type.
      Example:

      // Get a serializer class from an annotation Optional<Class<? extends Serializer>> serializerClass = annotationInfo.getClassValue("serializer", Serializer.class);

      Type Parameters:
      T - The expected supertype of the class.
      Parameters:
      methodName - The method name.
      type - The expected supertype of the class value.
      Returns:
      An optional containing the value of the specified method cast to the expected type, or empty if not found, not a class, or not assignable to the expected type.
    • getDouble

      public Optional<Double> getDouble(String methodName)
      Returns the value of the specified method on this annotation as a double.
      Example:

      // For annotation: @MyAnnotation(threshold=0.95) AnnotationInfo<MyAnnotation> ai = ...; double threshold = ai.getDouble("threshold").orElse(0.0); // Returns 0.95

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as a double, or empty if not found or not a double type.
    • getFloat

      public Optional<Float> getFloat(String methodName)
      Returns the value of the specified method on this annotation as a float.
      Example:

      // For annotation: @MyAnnotation(weight=0.5f) AnnotationInfo<MyAnnotation> ai = ...; float weight = ai.getFloat("weight").orElse(0.0f); // Returns 0.5f

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as a float, or empty if not found or not a float type.
    • getInt

      public Optional<Integer> getInt(String methodName)
      Returns the value of the specified method on this annotation as an integer.
      Example:

      // For annotation: @MyAnnotation(priority=5) AnnotationInfo<MyAnnotation> ai = ...; int priority = ai.getInt("priority").orElse(0); // Returns 5

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as an integer, or empty if not found or not an int type.
    • getLong

      public Optional<Long> getLong(String methodName)
      Returns the value of the specified method on this annotation as a long.
      Example:

      // For annotation: @MyAnnotation(timestamp=1234567890L) AnnotationInfo<MyAnnotation> ai = ...; long timestamp = ai.getLong("timestamp").orElse(0L); // Returns 1234567890L

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as a long, or empty if not found or not a long type.
    • getMethod

      public Optional<MethodInfo> getMethod(String methodName)
      Returns the method with the specified name on this annotation.
      Example:

      AnnotationInfo<MyAnnotation> ai = ...; Optional<MethodInfo> method = ai.getMethod("value"); method.ifPresent(m -> System.out.println(m.getReturnType()));

      Parameters:
      methodName - The method name to look for.
      Returns:
      An Optional containing the method info, or empty if method not found.
    • getName

      public String getName()
      Returns the simple class name of this annotation.
      Example:

      AnnotationInfo<MyAnnotation> ai = ...; String name = ai.getName(); // Returns "MyAnnotation"

      Returns:
      The simple class name of the annotation (e.g., "Override" for @Override).
    • getRank

      public int getRank()
      Returns the rank of this annotation for sorting by precedence.

      The rank is determined by checking if the annotation has a rank() method that returns an int. If found, that value is used; otherwise the rank defaults to 0.

      Higher rank values indicate higher precedence when multiple annotations of the same type are present.

      Example:

      // Annotation with rank method @interface MyAnnotation { int rank() default 0; } // Get rank from annotation info AnnotationInfo<MyAnnotation> ai = ...; int rank = ai.getRank(); // Returns value from rank() method

      Returns:
      The rank of this annotation, or 0 if no rank method exists.
    • getReturnType

      public Optional<ClassInfo> getReturnType(String methodName)
      Returns the return type of the specified method on this annotation.
      Example:

      Optional<ClassInfo> returnType = annotationInfo.getReturnType("value");

      Parameters:
      methodName - The method name.
      Returns:
      An optional containing the return type of the specified method, or empty if method not found.
    • getString

      public Optional<String> getString(String methodName)
      Returns the value of the specified method on this annotation as a string.
      Example:

      // For annotation: @MyAnnotation(name="John", age=30) AnnotationInfo<MyAnnotation> ai = ...; String name = ai.getString("name").orElse("unknown"); // Returns "John"

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the value as a string, or empty if not found or not a string type.
    • getStringArray

      public Optional<String[]> getStringArray(String methodName)
      Returns the value of the specified method on this annotation as a string array.
      Example:

      // For annotation: @MyAnnotation(tags={"foo", "bar"}) AnnotationInfo<MyAnnotation> ai = ...; String[] tags = ai.getStringArray("tags").orElse(new String[0]); // Returns ["foo", "bar"]

      Parameters:
      methodName - The method name.
      Returns:
      An Optional containing the string array value, or empty if not found or not a String[] type.
    • getValue

      Returns the value of the value() method on this annotation as a string.

      This is a convenience method equivalent to calling getString("value").

      Example:

      // For annotation: @MyAnnotation("foo") AnnotationInfo<MyAnnotation> ai = ...; String value = ai.getValue().orElse("default"); // Returns "foo"

      Returns:
      An Optional containing the value of the value() method, or empty if not found or not a string.
    • getValue

      public <V> Optional<V> getValue(Class<V> type, String name)
      Returns the value of a specific annotation method.

      This method provides type-safe access to annotation field values without requiring explicit reflection calls or casting.

      Example:

      // For annotation: @interface MyAnnotation { String value(); int priority(); } AnnotationInfo<MyAnnotation> ai = ...; // Get string value Optional<String> value = ai.getValue(String.class, "value"); // Get int value Optional<Integer> priority = ai.getValue(Integer.class, "priority");

      Type Parameters:
      V - The expected type of the annotation field value.
      Parameters:
      type - The expected class of the annotation field value.
      name - The name of the annotation method (field).
      Returns:
      An Optional containing the value if found and type matches, empty otherwise.
    • hasAnnotation

      public <A extends Annotation> boolean hasAnnotation(Class<A> type)
      Returns true if this annotation is itself annotated with the specified annotation.

      This checks for meta-annotations on the annotation type.

      Example:

      // Check if @MyAnnotation is annotated with @Documented AnnotationInfo<MyAnnotation> ai = ...; boolean isDocumented = ai.hasAnnotation(Documented.class);

      Type Parameters:
      A - The meta-annotation type.
      Parameters:
      type - The meta-annotation to test for.
      Returns:
      true if this annotation is annotated with the specified annotation.
    • hashCode

      public int hashCode()
      Returns the hash code of this annotation.

      Same as calling Annotation.hashCode() on the wrapped annotation.

      The hash code of an annotation is the sum of the hash codes of its members (including those with default values).

      Overrides:
      hashCode in class Object
      Returns:
      The hash code of this annotation.
      See Also:
    • hasName

      public boolean hasName(String value)
      Returns true if this annotation has the specified fully-qualified name.
      Example:

      boolean isName = annotationInfo.hasName("org.apache.juneau.annotation.Name");

      Parameters:
      value - The fully-qualified name to check.
      Returns:
      true if this annotation has the specified fully-qualified name.
    • hasSimpleName

      public boolean hasSimpleName(String value)
      Returns true if this annotation has the specified simple name.
      Example:

      boolean isName = annotationInfo.hasSimpleName("Name");

      Parameters:
      value - The simple name to check.
      Returns:
      true if this annotation has the specified simple name.
    • inner

      public T inner()
      Returns the wrapped annotation instance.
      Example:

      AnnotationInfo<MyAnnotation> ai = ...; MyAnnotation annotation = ai.inner(); // Access annotation methods directly String value = annotation.value();

      Returns:
      The wrapped annotation instance.
    • isInGroup

      public <A extends Annotation> boolean isInGroup(Class<A> group)
      Returns true if this annotation is in the specified AnnotationGroup.

      Annotation groups are used to logically group related annotations together. This checks if the annotation is annotated with AnnotationGroup and if the group value matches the specified type.

      Example:

      // Define an annotation group @interface MyGroup {} // Annotation in the group @AnnotationGroup(MyGroup.class) @interface MyAnnotation {} // Check if annotation is in group AnnotationInfo<MyAnnotation> ai = ...; boolean inGroup = ai.isInGroup(MyGroup.class); // Returns true

      Type Parameters:
      A - The group annotation type.
      Parameters:
      group - The group annotation class to test for.
      Returns:
      true if this annotation is in the specified group.
      See Also:
    • isType

      public <A extends Annotation> boolean isType(Class<A> type)
      Returns true if this annotation is of the specified type.
      Example:

      AnnotationInfo<?> ai = ...; if (ai.isType(MyAnnotation.class)) { // Handle MyAnnotation specifically }

      Type Parameters:
      A - The annotation type to test for.
      Parameters:
      type - The annotation type to test against.
      Returns:
      true if this annotation's type is exactly the specified type.
    • properties

      Converts this annotation info to a map representation for debugging purposes.

      The returned map contains:

      • The annotatable element's type and label (e.g., "CLASS_TYPE" -> "com.example.MyClass")
      • A nested map with the annotation's simple name as key and its non-default values

      Only annotation values that differ from their default values are included.

      Example:

      AnnotationInfo<MyAnnotation> ai = ...; LinkedHashMap<String,Object> map = ai.toMap(); // Returns: {"CLASS_TYPE": "MyClass", "@MyAnnotation": {"value": "foo", "priority": 5}}

      Returns:
      A new map showing the attributes of this annotation info.
    • toSimpleString

      Returns a simple string representation of this annotation showing the annotation type and location.

      Format: @AnnotationName(on=location)

      Examples:
      • @Rest(on=MyClass) - Annotation on a class
      • @RestGet(on=MyClass.myMethod) - Annotation on a method
      • @Inject(on=MyClass.myField) - Annotation on a field
      • @PackageAnnotation(on=my.package) - Annotation on a package
      Returns:
      A simple string representation of this annotation.
    • toString

      public String toString()
      Returns a string representation of this annotation.

      Returns the map representation created by properties().

      Overrides:
      toString in class Object
      Returns:
      A string representation of this annotation.