Closures are one of the most powerful and flexible features in Groovy. If you're coming from a Java background, closures might seem similar to anonymous inner classes or lambdas. Still, Groovy closures go far beyond that in terms of syntax simplicity and runtime flexibility.
In this tutorial, we’ll explore the basics of Groovy closures — what they are, how to use them, and how they make Groovy scripts more expressive and concise.
Preparation
To follow along and run the code examples in this tutorial, you must install Groovy. Here are a few ways to get started quickly:
Option 1: Install Groovy Locally
1. Using SDKMAN (recommended)
If you're on macOS or Linux, run:
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install groovy
2. Verify Installation
groovy --version
3. Run Groovy Scripts
Save code to a file like example.groovy, then run:
groovy example.groovy
Option 2: Use Groovy Console (GUI)
Groovy also includes a desktop GUI tool called Groovy Console:
groovyConsole
You can copy-paste any code example into this console and run it interactively.
Option 3: Try Online (No Install)
Use an online Groovy playground like:
What is a Closure in Groovy?
A closure in Groovy is a block of code that can be assigned to a variable, passed as a parameter, or executed at a later time. It can access variables defined outside its scope, making it very useful for functional-style programming.
Closures are instances of the groovy.lang.Closure class.
Closure Syntax
Here's the basic syntax of a Groovy closure:
def myClosure = { println "Hello from a closure!" }
myClosure() // Output: Hello from a closure!
You define it using {} and optionally include parameters before the -> symbol.
def greet = { name -> println "Hello, $name!" }
greet("Groovy") // Output: Hello, Groovy!
Closure with Parameters
You can define closures with one or more parameters:
def add = { a, b -> return a + b }
println add(3, 5) // Output: 8
Groovy allows omitting the parameter declaration when only one parameter is expected. In that case, it is used by default:
def square = { it * it }
println square(4) // Output: 16
Closures are First-Class Citizens
Since closures are objects, you can:
- Assign them to variables
- Pass them as arguments to methods
- Return them from other methods
Example of passing a closure:
def repeat(times, closure) {
for (int i = 0; i < times; i++) {
closure(i)
}
}
repeat(3, { println "Running iteration ${it + 1}" })
Closure Return Value
Closures return the result of the last expression:
def multiply = { a, b -> a * b }
def result = multiply(6, 7)
println result // Output: 42
You can also explicitly return a value using return, but it's usually optional.
Closures vs Lambdas
If you’re familiar with Java lambdas, closures offer even more flexibility. For example:
- They can have an implicit parameter (it)
- They can access and modify surrounding variables
- They support delegation (which we’ll cover in a future tutorial)
Conclusion
Closures in Groovy provide a concise, expressive, and powerful way to write code. They are core to many Groovy idioms and used widely in collections, file handling, Gradle build scripts, and more.
In the next tutorials, we'll cover:
- Closures with Collections
- Understanding Closure Scope (this, owner, delegate)
- Advanced Closure Features
- Real-World Scripting with Closures
Stay tuned — or subscribe to our newsletter for updates as new Groovy tutorials go live!
You can find the full source for this tutorial on our GitHub.
That's just the basics. If you need more deep learning about Groovy and Grails, you can take the following cheap course:
- Mastering Grails. A Comprehensive Grails Course.
- Groovy Scripting for Developers / Testers
- Introduction to JVM Languages: Clojure, Kotlin, and Groovy
Thanks!