The delegate keyword is widely used in Groovy. This post will explain how to use the delegate keyword.

As the official document :

 
 
this : as in Java, this refers to the instance of the enclosing class where a Closure is defined
 
owner : the enclosing object (this or a surrounding Closure)
 
delegate : by default the same as owner, but changeable for example in a builder or ExpandoMetaClass
 
 

Lets see an example:

 
class Class1 {
    def num = 1
 
    def thisAdd = {
        this.num++
    }
 
    def ownerAdd = {
        owner.num++
    }
 
    def delegateAdd = {
        delegate.num++
    }
 
    static void main(args) {
        def t = new Class1()
        t.thisAdd();
        println t.num
 
        t.ownerAdd();
        println t.num
 
        t.delegateAdd();
        println t.num
    }
}
 

The output :

 
2
3
4
 

The this, owner and delegate all reference to Class1, just like the document described.

But there are some tricks about delegate keyword you may not know.

 
 
class Class2 {
 
    int num = 1
 
    def static add = {
        delegate.num++
    }
 
    static void main ( args ) {
        Class1.add()
    }
}
 
 

The interpreter will report "No such property" error. The reason is the closure is static, so the delegate can only reference static variable which is not present in Class2. We can make the num static :

 
class Class2 {
 
    static int num = 1
 
    ...
}
 
 

Another example

 
class Class3 {
 
    def num = 1
 
    def add = {
           def num =2
           num++
    }
 
  static void main(args) {
 
       def t = new Class3()
 
       t.add()
 
       println t.num
 
  }
 
}
 
 

The result is 1. What if the num definition in closure removed.

 
class Class3 {
 
    def num = 1
 
    def add = {
 
           num++
    }
 
    ...
 
}
 
 

The output will be 2. Obviously , when reference variable in closure, if the variable is not defined in closure , it will use delegate to find the variable, if its not found either, report "No such property " error.

When reference variable name without modifier and the variable is not defined in closure , its equivalent to reference the variable with delegate.