Package groovy.transform
Annotation Type 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'] invalid input: '&'invalid input: '&' 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.
@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:
-
Optional Element Summary
Optional Elements
-
Element Details
-
excludes
String excludesComma 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
String includesComma 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:
""
-