[Java] Annotation Type Canonical
- groovy.transform.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
You don't need to provide all arguments in constructor calls. If using named parameters, any property names not referenced will be given their default value (as per Java's default unless an explicit initialization constant is provided when defining the property). If using a tuple constructor, parameters are supplied in the order in which the properties are defined. Supplied parameters fill the tuple from the left. Any parameters missing on the right are given their 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
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
- Authors:
- Paulo Poiati
- Paul King
- See Also:
- EqualsAndHashCode
- ToString
- TupleConstructor
- Immutable
- Since:
- 1.8.0
Element Summary
Type | Name and Description |
---|---|
String[] |
excludes List of field and/or property names to exclude. |
String[] |
includes List of field and/or property names to include. |
Inherited Methods Summary
Methods inherited from class | Name |
---|---|
class Object | wait, wait, wait, equals, toString, hashCode, getClass, notify, notifyAll |
Element Detail
public 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 {}
public 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 {}
© 2003-2020 The Apache Software Foundation
Licensed under the Apache license.
https://docs.groovy-lang.org/2.4.21/html/gapi/groovy/transform/Canonical.html