Enums, Records and Sealed Types
19.1 Enums
enum Color { RED, GREEN, BLUE }
enum Planet {
MERCURY(3.303e+23, 2.4397e6), EARTH(5.976e+24, 6.37814e6)
final double mass, radius
Planet(double mass, double radius) { this.mass = mass; this.radius = radius }
double surfaceGravity() { 6.67300E-11 * mass / (radius * radius) }
}
enum Op {
PLUS { int apply(int a, int b) { a + b } },
TIMES { int apply(int a, int b) { a * b } }
abstract int apply(int a, int b)
}
println Color.values(), Color.RED.ordinal(), Color.valueOf('GREEN'), 'BLUE' as Color
println Planet.EARTH.surfaceGravity().round(2)
println Op.TIMES.apply(3, 4)
def c = Color.GREEN
switch (c) { case Color.RED: println "stop"; break; case Color.GREEN: println "go"; break }
for (col in Color) println col
println (Color.RED..Color.BLUE) // enums support ranges19.2 Records (Groovy 4)
Records are immutable. They compile to native JVM records on JDK 16+ (or emulated records on older JDKs). @RecordOptions customizes them.
record Point(int x, int y) {
Point { // compact constructor (validation)
if (x < 0) throw new IllegalArgumentException("x < 0")
}
double distance() { Math.sqrt(x * x + y * y) }
}
def p = new Point(3, 4)
println p, p.x(), p.x, p.distance() // property-style access works too
def (px, py) = p // destructuring (Groovy records support getAt)
println p == new Point(3, 4) // structural equality
println p.copyWith(y: 10) // copyWith (record option)
println p.toMap()19.3 Sealed Types (Groovy 4)
@Sealed(permittedSubclasses = [...]) is the annotation alternative. Native JVM sealed classes are generated on JDK 17+.
sealed interface Shape permits Circle, Rect {}
final class Circle implements Shape { double r }
final class Rect implements Shape { double w, h }
// non-sealed class Other implements Shape {} // must be listed in permits
def area(Shape s) {
switch (s) {
case Circle -> Math.PI * s.r ** 2
case Rect -> s.w * s.h
}
}