Groovy Closures this owner delegate 的含义

Groovy Closures this owner delegate 的含义


Owner, delegate and this

this  corresponds to the enclosing class where the closure is defined

owner  corresponds to the enclosing object where the closure is defined, which may be either a class or a closure

delegate  corresponds to a third party object where methods calls or properties are resolved whenever the receiver of the message is not defined


要想了解Groovy闭包中的this,owner和delegate的含义,首先我们需要知道闭包能在哪些上下文中进行创建。

 

创建闭包的上下文

首先,闭包可以在方法体中创建(类的实例方法或者静态方法均可)

closures_app2.groovy

class Student {

    def static method() {
        def methodClosure = {
            println "methodClosure this:" + this
            println "methodClosure owner:" + owner
            println "methodClosure delegate:" + delegate
        }
        methodClosure
    }
}

Student.method().call()

运行输出,

methodClosure this:class com.usoft.Student

methodClosure owner:class com.usoft.Student

methodClosure delegate:class com.usoft.Student


其次, 闭包可以在类中直接定义:

closures_app2.groovy

class HelloWorld {
    def static classClosure = {
        println "classClosure this:" + this
        println "classClosure owner:" + owner
        println "classClosure delegate:" + delegate
    }

}

HelloWorld.classClosure.call()

运行输出如下,

classClosure this:class com.usoft.HelloWorld

classClosure owner:class com.usoft.HelloWorld

classClosure delegate:class com.usoft.HelloWorld


再者,闭包可以在groovy的script中直接定义,实际上也是在类中直接定义,同上,因为groovy的script实际上会被编译为Script.class

closures_app2.groovy

def scriptClosure = {
    println "scriptClosure this:" + this
    println "scriptClosure owner:" + owner
    println "scriptClosure delegate:" + delegate
}

scriptClosure.call()

运行输出如下,

scriptClosure this:com.usoft.closures_app2@1a451d4d
scriptClosure owner:com.usoft.closures_app2@1a451d4d
scriptClosure delegate:com.usoft.closures_app2@1a451d4d


最后, 闭包可以在闭包中定义:

closures_app2.groovy

def closure = {
    def closureClosure = {
        println "closureClosure this:" + this
        println "closureClosure owner:" + owner
        println "closureClosure delegate:" + delegate
    }
    closureClosure.call()
}

closure.call()

运行并输出,

closureClosure this:com.usoft.closures_app2@15ff3e9e

closureClosure owner:com.usoft.closures_app2$_run_closure2@3ce1e309

closureClosure delegate:com.usoft.closures_app2$_run_closure2@3ce1e309


从上可以看到,闭包可以在四种上下文中进行定义,但是闭包中的this,owner 和 delegate的含义却各不相同。 


静态闭包和实例闭包

如下代码,closures_app3.groovy

package com.usoft

/**
 * @author: Lenovo ( 2015 - 04 - 19 22 : 09 )
 */

class ClosureTest {

    /**
     * 类的静态闭包
     */
    def static classClosure = {
        println "classClosure this:" + this
        println "classClosure owner:" + owner
        println "classClosure delegate:" + delegate
    }

    /**
     * 类的实例闭包
     */
    def instanceClosure = {
        println "instanceClosure this:" + this
        println "instanceClosure owner:" + owner
        println "instanceClosure delegate:" + delegate
    }

    /**
     * 静态方法中的闭包
     * @return
     */
    def static classMethodClosure() {
        def classMethodClosure = {
            println "classMethodClosure this:" + this
            println "classMethodClosure owner:" + owner
            println "classMethodClosure delegate:" + delegate
        }
        classMethodClosure.call()
    }

    /**
     * 实例方法中的闭包
     * @return
     */
    def instanceMethodClosure() {
        def instanceMethodClosure = {
            println "instanceMethodClosure this:" + this
            println "instanceMethodClosure owner:" + owner
            println "instanceMethodClosure delegate:" + delegate
        }
        instanceMethodClosure.call()
    }
}

println "======================="
ClosureTest.classClosure()
println "======================="
new ClosureTest().instanceClosure()
println "======================="
ClosureTest.classMethodClosure()
println "======================="
new ClosureTest().instanceMethodClosure()

运行并输出,

=======================

classClosure this:class com.usoft.ClosureTest

classClosure owner:class com.usoft.ClosureTest

classClosure delegate:class com.usoft.ClosureTest

=======================

instanceClosure this:com.usoft.ClosureTest@8dbdac1

instanceClosure owner:com.usoft.ClosureTest@8dbdac1

instanceClosure delegate:com.usoft.ClosureTest@8dbdac1

=======================

classMethodClosure this:class com.usoft.ClosureTest

classMethodClosure owner:class com.usoft.ClosureTest

classMethodClosure delegate:class com.usoft.ClosureTest

=======================

instanceMethodClosure this:com.usoft.ClosureTest@74e52303

instanceMethodClosure owner:com.usoft.ClosureTest@74e52303

instanceMethodClosure delegate:com.usoft.ClosureTest@74e52303


This在闭包中的含义

对于this来讲,它基本上保持了跟java中this一样的含义(在java的静态方法以及静态域中,this是没有任何含义的),在上面的闭包创建的4种上下文中,实际上可以认为只有2种,一种是在普通的类中定义,如上面的Person类,一种是在groovy script中定义,实际上也是在类中定义,只不过这个是一个比较特殊的类而已, 所以,this在闭包中的含义指的是,表示定义该闭包的类的实例对象(实例闭包)或者类本身(静态闭包)

 

Owner在闭包中的含义

对于owner来讲,它的含义基本上跟this的含义一样,只是除了一种情况,如果该闭包是在其他的闭包中定义的,那么owner是指向定义它的闭包对象。 如上面最后一种创建上下文:

 闭包可以在闭包中定义:

closures_app2.groovy

def closure = {
    def closureClosure = {
        println "closureClosure this:" + this
        println "closureClosure owner:" + owner
        println "closureClosure delegate:" + delegate
    }
    closureClosure.call()
}

closure.call()

运行并输出,

closureClosure this:com.usoft.closures_app2@15ff3e9e

closureClosure owner:com.usoft.closures_app2$_run_closure2@3ce1e309

closureClosure delegate:com.usoft.closures_app2$_run_closure2@3ce1e309


Delegate在闭包中的含义

对于delegate来讲,它的含义大多数情况下是跟owner的含义一样,除非它被显示的修改(通过Closure.setDelegate()方法进行修改)。

在上面的几种创建上下文中,可以看到,如果闭包的delegate没有被显示改动的话,那么delegate确实是同owner是一个含义。下面我们看看修改delegate的情况:

closures_app4.groovy

package com.usoft

/**
 * @author: Lenovo ( 2015 - 04 - 19 22 : 20 )
 */

def scriptClosure = {
    println "scriptClosure this:" + this
    println "scriptClosure owner:" + owner
    println "scriptClosure delegate:" + delegate
}
println "before setDelegate()"
scriptClosure.call()
scriptClosure.setDelegate("abc")
println "after setDelegate()"
scriptClosure.call()

运行并输出,

before setDelegate()

scriptClosure this:com.usoft.closures_app4@7714e963

scriptClosure owner:com.usoft.closures_app4@7714e963

scriptClosure delegate:com.usoft.closures_app4@7714e963

after setDelegate()

scriptClosure this:com.usoft.closures_app4@7714e963

scriptClosure owner:com.usoft.closures_app4@7714e963

scriptClosure delegate:abc


其中,delegate可以被设置为任意一个对象。

下面可以看下groovy中使用了setDelegate的应用:

package com.usoft

/**
 * @author: Lenovo ( 2015 - 04 - 19 22 : 22 )
 */

String.metaClass.doTestClosure = {
    println "doTestClosure this:" + this
    println "doTestClosure owner:" + owner
    println "doTestClosure delegate:" + delegate
}
"do test".doTestClosure()


Integer.metaClass.doTestClosure = {
    println "doTestClosure this:" + this
    println "doTestClosure owner:" + owner
    println "doTestClosure delegate:" + delegate
}
1.doTestClosure()

运行并输出,

doTestClosure this:com.usoft.closures_app5@67d48005

doTestClosure owner:com.usoft.closures_app5@67d48005

doTestClosure delegate:do test

doTestClosure this:com.usoft.closures_app5@67d48005

doTestClosure owner:com.usoft.closures_app5@67d48005

doTestClosure delegate:1

可以看到,在通过metaClass动态添加方法时,delegate都被动态的设置为了调用者的实例本身,如上面的"do test"字符窜,以及整数1. 

setDelegate还被广泛的使用于groovy builder的构建中。有兴趣的可以看下groovy中BuildSupport的实现。



你可能感兴趣的:(Groovy Closures this owner delegate 的含义)