Search

Dark theme | Light theme

May 24, 2011

Groovy Goodness: Canonical Annotation to Create Mutable Class

With Groovy 1.8 we get a lot of AST transformations. We can combine @ToString, @EqualsAndHashCode and @TupleConstructor with the @Canonical annotation. This annotation will do all the transformations at once. If we want to customize one of the AST transformations, we add the annotation with configuration parameters extra after @Canonical.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import groovy.transform.*
 
@Canonical
class Building {
    String name
    int floors
    boolean officeSpace
}
 
// Constructors are added.
def officeSpace = new Building('Initech office', 1, true)
 
// toString() added.
assert officeSpace.toString() == 'Building(Initech office, 1, true)'
 
// Default values are used if constructor
// arguments are not assigned.
def theOffice = new Building('Wernham Hogg Paper Company')
assert theOffice.floors == 0
theOffice.officeSpace = true
 
def anotherOfficeSpace = new Building(name: 'Initech office', floors: 1, officeSpace: true)
 
// equals() method is added.
assert anotherOfficeSpace == officeSpace
 
// equals() and hashCode() are added, so duplicate is not in Set.
def offices = [officeSpace, anotherOfficeSpace, theOffice] as Set 
assert offices.size() == 2
assert offices.name.join(',') == 'Initech office,Wernham Hogg Paper Company'
 
@Canonical
@ToString(excludes='age'// Customize one of the transformations.
class Person {
    String name
    int age
}
 
def mrhaki = new Person('mrhaki', 37)
assert mrhaki.toString() == 'Person(mrhaki)'