Groovy - Annotations



Annotations are a form of metadata wherein they provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.

Annotations are mainly used for the following reasons −

  • Information for the compiler − Annotations can be used by the compiler to detect errors or suppress warnings.

  • Compile-time and deployment-time processing − Software tools can process annotation information to generate code, XML files, and so forth.

  • Runtime processing − Some annotations are available to be examined at runtime.

In Groovy, a basic annotation looks as follows −

@interface - The at sign character (@) indicates to the compiler that what follows is an annotation.

An annotation may define members in the form of methods without bodies and an optional default value.

Annotation’s can be applied to the following types −

String Type

An example of an Annotation for a string is given below −

@interface Simple { 
   String str1() default "HelloWorld"; 
}

Enum type

enum DayOfWeek { mon, tue, wed, thu, fri, sat, sun } 
@interface Scheduled {
   DayOfWeek dayOfWeek() 
} 

Class type

@interface Simple {} 
@Simple 
class User {
   String username
   int age
}
 
def user = new User(username: "Joe",age:1); 
println(user.age); 
println(user.username);

Annotation Member Values

When an annotation is used, it is required to set at least all members that do not have a default value. An example is given below. When the annotation Example is used after being defined, it needs to have a value assigned to it.

@interface Example {
   int status() 
}

@Example(status = 1)

Closure Annotation Parameters

A good feature of annotations in Groovy is that you can use a closure as an annotation value also. Therefore annotations may be used with a wide variety of expressions.

An example is given below on this. The annotation Onlyif is created based on a class value. Then the annotation is applied to two methods which posts different messages to the result variable based on the value of the number variable.

@interface OnlyIf {
   Class value() 
}  

@OnlyIf({ number<=6 }) 
void Version6() {
   result << 'Number greater than 6' 
} 

@OnlyIf({ number>=6 }) 
void Version7() {
   result << 'Number greater than 6' 
}

Meta Annotations

This is quite a useful feature of annotations in groovy. There may comes times wherein you might have multiple annotations for a method as the one shown below. Sometimes this can become messy to have multiple annotations.

@Procedure 
@Master class 
MyMasterProcedure {} 

In such a case you can define a meta-annotation which clubs multiple annotations together and the apply the meta annotation to the method. So for the above example you can fist define the collection of annotation using the AnnotationCollector.

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector

Once this is done, you can apply the following meta-annotator to the method −

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector
  
@MasterProcedure 
class MyMasterProcedure {}
Advertisements