Groovy Closure Scope: this, owner, and delegate Explained

by Didin J. on May 15, 2025 Groovy Closure Scope: this, owner, and delegate Explained

Learn how Groovy resolves this, owner, and delegate in closures. Control scope and build custom DSLs with practical examples

When you start nesting or delegating closures in Groovy, understanding how scope resolution works becomes crucial. In this tutorial, we’ll demystify the three key references inside a closure—this, owner, and delegate—and show you how to control them to build powerful DSLs and scripts.


Preparation

Make sure Groovy is installed. You can use:

  • SDKMAN (Linux/macOS):
sdk install groovy
  • Groovy Console for interactive editing:
groovyConsole

Online editors like TutorialsPoint Groovy Editor https://www.tutorialspoint.com/compilers/online-groovy-compiler.htm

Groovy Closure Scope: this, owner, and delegate Explained - TP Groovy Console

Save code in ClosureScopeExample.groovy and run with groovy ClosureScopeExample.groovy.


What is this owner, and delegate?

  • this

Points to the enclosing class or script instance where the closure is defined.

  • owner

The immediate enclosing object of the closure—either the class/script or another closure if nested.

  • delegate

A supplementary reference that you can set at runtime to redirect method/property resolution. By default, it’s the same as the owner.


Example: Default Resolution

class ScopeDemo {
    def name = 'ScopeDemo'

    def runDemo() {
        def closure = {
            println "this.name: ${this.name}"
            println "owner.name: ${owner.name}"
            println "delegate.name: ${delegate.name}"
        }
        closure()
    }
}

new ScopeDemo().runDemo()

Output:

this.name: ScopeDemo
owner.name: ScopeDemo
delegate.name: ScopeDemo

Here, all three resolve to the ScopeDemo instance.


Nested Closures and owner

def outer = {
    def inner = {
        println "owner is outer? " + (owner == outer)
        println "this is script? "  + (this instanceof GroovyScript)
    }
    inner()
}

outer()

Output:

owner is outer? true
this is script? true
  • owner of the inner closure is the outer closure.
  • *his remains the script instance.


Changing the delegate and the Resolve Strategy

You can redirect method/property calls to a different object by changing the delegate and using resolve strategies:

class Person {
    String name
}

def closure = {
    println "Hello, $name!"
}

def p = new Person(name: 'Alice')
closure.delegate = p
closure.resolveStrategy = Closure.DELEGATE_FIRST

closure()  // Output: Hello, Alice!
  • Closure.DELEGATE_FIRST tries the delegate before owner.
  • Closure.OWNER_FIRST (default) tries the owner before delegate.


Practical DSL Example

Building a tiny HTML builder:

class HtmlBuilder {
    def content = ''

    def html(Closure cl) {
        cl.delegate = this
        cl.resolveStrategy = DELEGATE_FIRST
        content += '<html>'
        cl()
        content += '</html>'
    }

    def body(Closure cl) {
        content += '<body>'
        cl.delegate = this
        cl.resolveStrategy = DELEGATE_FIRST
        cl()
        content += '</body>'
    }

    def p(String text) {
        content += "<p>${text}</p>"
    }
}

def builder = new HtmlBuilder()
builder.html {
    body {
        p 'Hello, World!'
    }
}
println builder.content

Output:

<html><body><p>Hello, World!</p></body></html>

Here delegate lets the closure call p directly on the builder.


Conclusion

Understanding this, owner, and delegate unlock Groovy’s full power for nested closures and custom DSLs. You now know how to:

  • Identify each reference in different contexts
  • Redirect resolution with delegate and resolveStrategy
  • Build concise, readable DSLs

You can find the full source for this tutorial on our GitHub.

That just the basic. If you need more deep learning about Groovy and Grails you can take the following cheap course:

Thanks!