Annotation Type Canonical


  • @Documented
    @Retention(SOURCE)
    @Target(TYPE)
    public @interface Canonical
    Class annotation used to assist in the creation of mutable classes.

    It allows you to write classes in this shortened form:

     @Canonical class Customer {
         String first, last
         int age
         Date since
         Collection favItems = ['Food']
         def object 
     }
     def d = new Date()
     def anyObject = new Object()
     def c1 = new Customer(first:'Tom', last:'Jones', age:21, since:d, favItems:['Books', 'Games'], object: anyObject)
     def c2 = new Customer('Tom', 'Jones', 21, d, ['Books', 'Games'], anyObject)
     assert c1 == c2
    
     If you set the autoDefaults flag to true, you don't need to provide all arguments in constructors calls,
     in this case all properties not present are initialized to the default value:
     def c3 = new Customer(last: 'Jones', age: 21)
     def c4 = new Customer('Tom', 'Jones')
     
     assert null == c3.since
     assert 0 == c4.age
     assert c3.favItems == ['Food'] && c4.favItems == ['Food']
     
     
    The @Canonical annotation instructs the compiler to execute an AST transformation which adds positional constructors, equals, hashCode and a pretty print toString to your class. There are additional annotations if you only need some of the functionality: @EqualsAndHashCode, @ToString and @TupleConstructor. In addition, you can add one of the other annotations if you need to further customize the behavior of the AST transformation.

    A class created in this way has the following characteristics:

    • A no-arg constructor is provided which allows you to set properties by name using Groovy's normal bean conventions.
    • Tuple-style constructors are provided which allow you to set properties in the same order as they are defined.
    • Default equals, hashCode and toString methods are provided based on the property values. Though not normally required, you may write your own implementations of these methods. For equals and hashCode, if you do write your own method, it is up to you to obey the general contract for equals methods and supply a corresponding matching hashCode method. If you do provide one of these methods explicitly, the default implementation will be made available in a private "underscore" variant which you can call. E.g., you could provide a (not very elegant) multi-line formatted toString method for Customer above as follows:
           String toString() {
              _toString().replaceAll(/\(/, '(\n\t').replaceAll(/\)/, '\n)').replaceAll(/, /, '\n\t')
          }
       
      If an "underscore" version of the respective method already exists, then no default implementation is provided.

    If you want similar functionality to what this annotation provides but also require immutability, see the @Immutable annotation.

    Limitations:

    • If you explicitly add your own constructors, then the transformation will not add any other constructor to the class.
    Since:
    1.8.0
    Author:
    Paulo Poiati, Paul King
    See Also:
    EqualsAndHashCode, ToString, TupleConstructor, Immutable
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element Description
      java.lang.String excludes
      Comma separated list of field and/or property names to exclude.
      java.lang.String includes
      Comma separated list of field and/or property names to include.
    • Element Detail

      • excludes

        java.lang.String excludes
        Comma separated list of field and/or property names to exclude. Must not be used if 'includes' is used. If the @Canonical behavior is customised by using it in conjunction with one of the more specific related annotations (i.e. @ToString, @EqualsAndHashCode or @TupleConstructor), then the value of this attribute can be overriden within the more specific annotation.
        Default:
        ""
      • includes

        java.lang.String includes
        Comma separated list of field and/or property names to include. Must not be used if 'excludes' is used. If the @Canonical behavior is customised by using it in conjunction with one of the more specific related annotations (i.e. @ToString, @EqualsAndHashCode or @TupleConstructor), then the value of this attribute can be overriden within the more specific annotation.
        Default:
        ""