Variables, Types and Optional Typing
4.1 Declaring Variables
In scripts, assigning to an undeclared variable puts it in the script binding (global-like): counter = 0.
def name = "Groovy" // dynamic type (Object reference, holds a String)
var count = 10 // same as def (Groovy 3+)
String lang = "Groovy" // static type declaration
int age = 30 // primitive (optimized)
final pi = 3.14159 // can't be reassigned
def (a, b, c) = [1, 2, 3] // multiple assignment
def (x, y) = "10 20".split()*.toInteger()
(a, b) = [b, a] // swap
def (first, second) = [1] // second == null4.2 Dynamic vs Static Types
Types are checked at runtime unless @TypeChecked / @CompileStatic is used (Module 23).
def value = 42
value = "now a string" // allowed: def is dynamic
String s = "text"
// s = 42 // runtime cast attempt: s becomes "42" (GString/Object → String coercion)
Integer n = "42" as Integer // explicit coercion with `as`4.3 Primitive and Wrapper Types
Default literal type byte, short, int, long Integer literals are Integer, then Long, then BigInteger as needed float, double
Decimal literals are BigDecimal by default No char literal ('a' as char) true / false
4.4 Checking Types
def v = 3.14
println v.class // class java.math.BigDecimal
println v instanceof Number // true
println v.getClass().simpleName
if (v in BigDecimal) println "BigDecimal" // `in` with a class calls isCase → instanceof