Package groovy.transform
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 == c2def 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
andtoString
methods are provided based on the property values. Though not normally required, you may write your own implementations of these methods. Forequals
andhashCode
, if you do write your own method, it is up to you to obey the general contract forequals
methods and supply a corresponding matchinghashCode
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 formattedtoString
method forCustomer
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
- Groovy's normal map-style naming conventions will not be available if the first property
has type
LinkedHashMap
or if there is a single Map, AbstractMap or HashMap property
- Since:
- 1.8.0
- Author:
- Paulo Poiati, Paul King
- See Also:
EqualsAndHashCode
,ToString
,TupleConstructor
,Immutable
-
-
Element Detail
-
excludes
java.lang.String[] excludes
List of field and/or property names to exclude. Must not be used if 'includes' is used. For convenience, a String with comma separated names can be used in addition to an array (using Groovy's literal list notation) of String values. 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 overridden within the more specific annotation.- Default:
- {}
-
-
-
includes
java.lang.String[] includes
List of field and/or property names to include. Must not be used if 'excludes' is used. For convenience, a String with comma separated names can be used in addition to an array (using Groovy's literal list notation) of String values. 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 overridden within the more specific annotation.- Default:
- {}
-
-