Skip to content
AgileLogics
6 min read

Closures

Prerequisites: Methods

A closure is a block of code you can store in a variable, pass to a method, and call later. Closures are the heart of idiomatic Groovy — you've already used them with each and times.

def square = { x -> x * x }
def greet = { name, greeting = 'Hello' -> "$greeting, $name!" }
def shout = { it.toUpperCase() + '!' }   // "it": the single implicit parameter
def now = { -> 'no parameters' }

println square(4)
println square.call(5)
println greet('Ada')
println greet('Linus', 'Hi')
println shout('hey')
println now()
16
25
Hello, Ada!
Hi, Linus!
HEY!
no parameters
  • Parameters go before ->; the body comes after.
  • With no ->, the closure has one implicit parameter named it.
  • { -> ... } declares a closure that takes no parameters.
  • The last expression is the return value.

Passing closures to methods

def repeat(int times, Closure action) {
    for (i in 1..times) action(i)
}

repeat(3) { n -> println "call number $n" }

def numbers = [1, 2, 3, 4, 5]
println numbers.collect { it * 10 }
println numbers.findAll { it % 2 == 1 }
println numbers.find { it > 3 }
call number 1
call number 2
call number 3
[10, 20, 30, 40, 50]
[1, 3, 5]
4

When the last argument of a method is a closure, you can write it after the parentheses — repeat(3) { ... } — or drop the parentheses completely if it's the only argument: numbers.each { ... }. That's what makes Groovy code (and Gradle and Jenkins files) read like a language of its own.

Closures capture variables

def counter = 0
def increment = { counter++ }

increment()
increment()
increment()
println counter

def makeMultiplier(factor) {
    return { value -> value * factor }
}
def triple = makeMultiplier(3)
println triple(7)
3
21

A closure can read and change variables from the scope where it was created, even after that scope has finished — triple still knows factor is 3. That's where the name "closure" comes from.

Method references

def words = ['groovy', 'java', 'kotlin']
println words.collect(String::toUpperCase)
println words.collect { it.capitalize() }
[GROOVY, JAVA, KOTLIN]
[Groovy, Java, Kotlin]

Java-style method references (Class::method) work in Groovy 3 and later. Level 2 goes much deeper: currying, composition, delegates, and how closures power builders and DSLs.