Classes, Properties and Constructors
16.1 Classes and Properties
class Person {
String name // property: private field + getName()/setName() generated
int age
final String id = UUID.randomUUID().toString() // read-only property (getter only)
private String secret // explicitly private field (no accessors generated)
protected String note
static int count = 0
String getDisplayName() { "$name ($age)" } // custom getter → displayName property
void setAge(int age) { // custom setter
if (age < 0) throw new IllegalArgumentException("negative age")
this.age = age
}
String toString() { "Person($name, $age)" }
}
def p = new Person(name: "Ana", age: 30) // named-argument constructor (default constructor + setters)
println p.name // calls getName()
p.age = 31 // calls setAge()
println p.displayName
println p.@age // direct field access
println p.properties // map of properties
println p['name'] // subscript property access
p.with { name = "Ana B."; age = 32 }16.2 Constructors
Without explicit constructors, Groovy supports new X(prop: value, ...). Add @TupleConstructor, @MapConstructor, or @Canonical for more options (Module 24).
class Point {
int x, y
Point() { this(0, 0) }
Point(int x, int y) { this.x = x; this.y = y }
}
def a = new Point(1, 2)
def b = [3, 4] as Point // list coercion calls the constructor
Point c = [5, 6] // implicit coercion on typed assignment
def d = new Point()16.3 Static Members, Inner Classes and Initializers
class Registry {
static final Map<String, Object> items = [:]
static { println "static initializer" }
{ println "instance initializer" }
static register(String k, v) { items[k] = v }
class Inner { def outerItems() { items } }
static class Nested {}
}
def anon = new Runnable() { void run() { println "anonymous inner class" } }16.4 Object Equality and Hashing
== calls equals(). Implement equals and hashCode (or use @EqualsAndHashCode / @Canonical).
is() / === test reference identity.