Getting Started with Annotation Contracts

Annotation Contracts is one of the new features of GContracts 1.2 [0]. The main principle behind is to reuse small but reoccurring parts of pre- and post-condition expressions. This article is about creating a simple @NotNull annotation contract. @NotNull can be applied on method parameters in order to automatically add null checks to the method's precondition.

Let's Get Started

The first step when creating an annotation contract is to create a custom annotation, in this case @NotNull.
 
@Precondition
@AnnotationContract({ it != null })
public @interface NotNull {}
 
Depending on whether the expression should be part of the pre- or post-condition, the author needs to specify @Precondition or @Postcondition (from the org.gcontracts.annotations.meta package). The expression which is supposed to be added to the precondition is specified with the @AnnotationContract annotation. The @AnnotationContract annotation has a single annotation closure which has to hold a boolean expression. The value of the parameter can be referenced with it. Note: @Retention and @Target are optional. GContracts will inject those meta-annotations if not available in the annotation contract definition. Currently, only ElementType.PARAMETER is supported.

How to Apply the Annotation Contract

Applying the annotation contracts is pretty straight-forward. Just add it to the appropriate parameter(s):
 
class Tester {
    def doSomething(@NotNull param) { println "hello world: ${param}" }
}
 
During the compilation process GContracts will inject a newly created precondition for method doSomething that will check parameter param. With a precondition already specified, the null check will be merged into the existing boolean expression by conjunction.

Summary

Annotation contracts are a simple way to reuse micro contracts, i.e. null checks, empty strings checks, range checks etc. GContracts 1.2 provides a neat way to create annotation contracts with the help of annotation closures.

[0] GContracts 1.2.0 Released!