Getting annotations at run time

You can get annotation information from a class either directly or by getting the type from an object at run time. You can get the type of an object at run time by using the typeof operator, such as: typeof TYPE.

Annotation access at run time

You can get annotation information from a type, a constructor, a method, or a property by accessing the metadata information objects that are attached to the type.

To get a single instance of a specific annotation, call the getAnnotation method on the type.

For a list of multiple annotation instances of one type, call the getAnnotationsOfType for the specified type.

To get an annotation from targets such as constructors, methods, or properties, call the getAnnotation method on the item, not on the type itself. The following table shows how to get an annotation from each target type. In the examples in the table, the variable i represents the index in the list. In practice, you would likely search for the required target by name using List methods like list.firstWhere(\ s -> s.Name = "MethodName").

Get annotations on this object

Example Gosu to access the example @MyAnnotation annotation

Type

(typeof obj).TypeInfo.getAnnotation(MyAnnotation)

Constructor for a type

(typeof obj).TypeInfo.Constructors[i].getAnnotation(MyAnnotation)

Method of a type

(typeof obj).TypeInfo.Methods[i].getAnnotation(MyAnnotation)

Property of a type

(typeof obj).TypeInfo.Properties[i].getAnnotation(MyAnnotation)

Getting multiple annotations of multiple types

You can get all annotations of any annotation type using the two properties Annotations and DeclaredAnnotations. These two properties resemble the Java versions of annotations of the same names.

On types and interfaces, Annotations returns all annotations on this type or interface and on all its supertypes or superinterfaces. DeclaredAnnotations returns annotations only on the given types, ignoring supertypes or superinterfaces.

In constructors, properties, and methods, the Annotations and DeclaredAnnotations properties return the same thing: all annotations including supertypes/superinterfaces. In the examples in the table, the variable i represents the index in the list. In practice, you would probably search for the required target by name using List methods like list.firstWhere(\ s -> s.Name = "MethodName").

Get all annotations on...

Example

Type

(typeof obj).TypeInfo.Annotations

Constructor

(typeof obj).TypeInfo.Constructors[i].Annotations

Method

(typeof obj).TypeInfo.Methods[i].Annotations

Property

(typeof obj).TypeInfo.Properties[i].Annotations

The return result of these methods is typed as a list of the expected type. Using the examples in the previous table, the result is of type List<MyAnnotation>. This type is shown using generics syntax, which means “a list of instances of the MyAnnotation annotation class”.

See also

Getting annotation data from a type at run time

You perform the following general tasks to get annotation data from a type at run time.

  1. Get a reference to a type. If you have a reference to an object instead of its type, get the type at run time using the typeof operator.
  2. Get the result’s TypeInfo property.
  3. To access annotations on the type, call the getAnnotation method, passing your annotation class name directly as a parameter. If you want to get annotations from the constructor, method, or property, get the subobject as described in the previous table, then call its getAnnotation method.
  4. On the result, get its Instance property or call its getInstance method. The Instance property throws an exception if there is more than one instance of that annotation on the type in that context.
  5. Cast the result to the desired annotation type using the as keyword. For example, suppose the result of the previous step is a variable called res and your annotation is called @MyAnnotation. Use the syntax: as MyAnnotation.
  6. From the result, get the data from the annotation instance with any annotation arguments defined as methods. For example, if an annotation has constructor arguments purpose and importance, get those values using methods purpose and importance.

Example

The classes example.MyClass and example.MyAnnotation demonstrate the prior steps:

package example

annotation MyAnnotation {
  function purpose() : String
  function importance() : int = 0
}

package example

@MyAnnotation(:purpose="to do the right thing", :importance=44)
class MyClass {
}

The following code uses the example.MyClass and example.MyAnnotation classes:

uses example.MyAnnotation
uses example.MyClass

// Get a reference to an object of that class
var c = new MyClass()

// Get the type info
var ti = (typeof c).TypeInfo

// Get the annotation of our specific annotation type
var ann = ti.getAnnotation(MyAnnotation).Instance as MyAnnotation

print("Purpose is " + ann.purpose())
print("Importance is " + ann.importance())

This example prints the following lines:

Purpose is to do the right thing
Importance is 44