How to define, apply, and access strongly typed annotations
- Last Updated: October 14, 2026
- 4 minute read
- OpenEdge
- Version 13.1
- Documentation
This topic shows how to define a strongly typed annotation, apply it to methods, and retrieve annotation values at runtime using the reflection API.
Define a strongly typed annotation class
Define a strongly typed annotation by creating a dedicated .cls file that uses the ANNOTATION statement. An annotation class describes the metadata structure by declaring one or more strongly typed properties.
For example, the following annotation class defines metadata for mapping a class element to a service endpoint:
|
Annotation classes have a constrained structure:
- They contain properties only.
- They define no methods, constructors, or events.
- Property values are read‑only at runtime.
- Only one annotation definition is allowed per
.clsfile.
Apply a strongly typed annotation
You can apply strongly typed annotations to methods to describe metadata such as service mappings, configuration, or framework behavior.
Use the [ ] Strongly typed annotation syntax and place it immediately before the declaration you want to annotate. The annotation should appear on its own line and is associated with the next applicable declaration.
The following example applies the ResourceMapping annotation to a method:
|
When the class is compiled:
- The compiler validates the annotation usage against the annotation class definition.
- The annotation metadata is stored in r‑code.
- Properties that are not explicitly assigned retain their default values, as defined either
by an
INITIALvalue in the annotation class or by the default value of the property’s data type.
Understand annotation placement and ordering rules
Strongly typed annotations are associated with the next applicable declaration in the source file. The compiler determines the association based on placement rules, not indentation or formatting.
Keep the following rules in mind when applying annotations:
- An annotation should appear on its own line and be terminated with a period. Place the annotation immediately before the declaration it annotates.
- An annotation applies to the next declaration that the compiler encounters, skipping blank lines, comments, and other annotations.
- You can apply multiple annotations to the same declaration by placing them on consecutive lines.
- You cannot apply the same annotation class more than once to a declaration.
- An annotation applies only to the declaration it precedes. Annotations are not inherited by subclasses or by overridden members.
For example, both annotations in the following code apply to the method:
|
If an annotation is placed in a location where annotations are not supported, the compiler raises an error.
If an annotation is not placed immediately before the intended declaration, it may be associated with a different element than you expect, or result in a compile‑time error. For example, in the following code, the annotation is not applied to the method:
|
In this case, the annotation applies to the DEFINE VARIABLE statement, not to
the method. If annotations are not supported on that declaration type, the compiler
raises an error.
To avoid this issue, always place the annotation directly before the declaration you want to annotate, with no intervening executable declarations.
Use marker annotations
An annotation class that defines no properties acts as a marker annotation. Marker annotations convey meaning through their presence alone.
For example:
|
Apply a marker annotation without specifying property values:
|
Parentheses are optional when using marker annotations.
Retrieve a specific annotation at runtime
To access annotations applied to a class or class member, use the GetAnnotation() method to retrieve a specific annotation, the GetAnnotations() method to retrieve all annotations, or the HasAnnotation() method to test for the presence of a marker annotation.
The following example retrieves the ResourceMapping annotation applied to a
method:
|
The annotation instance returned by GetAnnotation() behaves like a
regular object-oriented ABL object, but its properties are read‑only.
Retrieve all annotations or test for marker annotations
Retrieve all annotations applied to an element by calling
GetAnnotations():
|
Test for the presence of a marker annotation by using
HasAnnotation():
|
These approaches are commonly used by frameworks and infrastructure code that adapts behavior based on annotation metadata.
Access annotation property values safely
When reading annotation properties:
- If an annotation property is not explicitly assigned in the annotation usage, its value is
taken from the
INITIALvalue specified in the annotation class, if one exists. - If no
INITIALvalue is specified, the property contains the default value for its data type.
Always account for default and unknown values when using annotation metadata in application logic.
Summary
Strongly typed annotations provide a structured way to define, apply, and access metadata in object-oriented ABL applications. By defining annotation classes, applying annotations enclosed in square brackets, and retrieving metadata through reflection, you can build applications and frameworks that are easier to configure, extend, and maintain without embedding metadata directly in executable code.