Groovy闭包中的this,owner和delegate
Posted duangxcg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy闭包中的this,owner和delegate相关的知识,希望对你有一定的参考价值。
要想了解Groovy闭包中的this,owner和delegate的含义,首先我们需要知道闭包能在哪些上下文中进行创建。
创建闭包的上下文
首先,闭包可以在方法体中创建(类的实例方法或者静态方法均可)
Java代码
- class Person
- def static method()
- def methodClosure=
- println "methodClosure this:"+this
- println "methodClosure owner:"+owner
- println "methodClosure delegate:"+delegate
- methodClosure
- Person.method().call()
输出:
methodClosure this:class test.Person
methodClosure owner:class test.Person
methodClosure delegate:class test.Person
其次, 闭包可以在类中直接定义:
Java代码
- class Person
- def static classClosure=
- println "classClosure this:"+this
- println "classClosure owner:"+owner
- println "classClosure delegate:"+delegate
- Person.classClosure.call()
输出:
classClosure this:class test.Person
classClosure owner:class test.Person
classClosure delegate:class test.Person
再者,闭包可以在groovy的script中直接定义,实际上也是在类中直接定义,同上,因为groovy的script实际上会被编译为Script.class
Java代码
- def scriptClosure=
- println "scriptClosure this:"+this
- println "scriptClosure owner:"+owner
- println "scriptClosure delegate:"+delegate
- scriptClosure.call()
输出:
scriptClosure this:test.Script@a09e41
scriptClosure owner:test.Script@a09e41
scriptClosure delegate:test.Script@a09e41
最后, 闭包可以在闭包中定义:
Java代码
- def closure=
- def closureClosure=
- println "closureClosure this:"+this
- println "closureClosure owner:"+owner
- println "closureClosure delegate:"+delegate
- closureClosure.call()
- closure.call()
输出:
closureClosure this:test.Script@27cd63
closureClosure owner:test.Script$_run_closure2@746ad0
closureClosure delegate:test.Script$_run_closure2@746ad0
从上可以看到,闭包可以在四种上下文中进行定义,但是闭包中的this,owner 和 delegate的含义却各不相同。
静态闭包和实例闭包
实际上,闭包根据其创建的上下文不同,还可以分为静态闭包和实例闭包,在这两种情况下,this,owner和delegate的含义也是不同的。
Java代码
- 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
- def static classMethodClosure()
- def classMethodClosure=
- println "classMethodClosure this:"+this
- println "classMethodClosure owner:"+owner
- println "classMethodClosure delegate:"+delegate
- classMethodClosure.call()
- def instanceMethodClosure()
- def instanceMethodClosure=
- println "instanceMethodClosure this:"+this
- println "instanceMethodClosure owner:"+owner
- println "instanceMethodClosure delegate:"+delegate
- instanceMethodClosure.call()
- ClosureTest.classClosure()
- new ClosureTest().instanceClosure()
- ClosureTest.classMethodClosure()
- new ClosureTest().instanceMethodClosure()
输出:
Java代码
- classClosure this:class test.ClosureTest
- classClosure owner:class test.ClosureTest
- classClosure delegate:class test.ClosureTest
- instanceClosure this:test.ClosureTest@11d3226
- instanceClosure owner:test.ClosureTest@11d3226
- instanceClosure delegate:test.ClosureTest@11d3226
- classMethodClosure this:class test.ClosureTest
- classMethodClosure owner:class test.ClosureTest
- classMethodClosure delegate:class test.ClosureTest
- instanceMethodClosure this:test.ClosureTest@ecb3f1
- instanceMethodClosure owner:test.ClosureTest@ecb3f1
- instanceMethodClosure delegate:test.ClosureTest@ecb3f1
This在闭包中的含义
对于this来讲,它基本上保持了跟java中this一样的含义(在java的静态方法以及静态域中,this是没有任何含义的),在上面的闭包创建的4种上下文中,实际上可以了解为只有2种,一种是在普通的类中定义,如上面的Person类,一种是在groovy script中定义,实际上也是在类中定义,只不过这个是一个比较特殊的类而已(Groovy会将groovy script编译为Script.class), 所以,this在闭包中的含义指的是,表示定义该闭包的类的实例对象(实例闭包)或者类本身(静态闭包)。
Owner在闭包中的含义
对于owner来讲,它的含义基本上跟this的含义一样,只是除了一种情况,如果该闭包是在其他的闭包中定义的,那么owner是指向定义它的闭包对象。 如上面最后一种创建上下文:
Java代码
- closureClosure owner:test.Script$_run_closure2@746ad0
Delegate在闭包中的含义
对于delegate来讲,它的含义大多数情况下是跟owner的含义一样,除非它被显示的修改(通过Closure.setDelegate()方法进行修改)。
在上面的几种创建上下文中,可以看到,如果闭包的delegate没有被显示改动的话,那么delegate确实是同owner是一个含义。下面我们看看修改delegate的情况:
Java代码
- 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()
输出:
Java代码
- before setDelegate()
- scriptClosure this:test.Script@67c1a6
- scriptClosure owner:test.Script@67c1a6
- scriptClosure delegate:test.Script@67c1a6
- after setDelegate()
- scriptClosure this:test.Script@67c1a6
- scriptClosure owner:test.Script@67c1a6
- scriptClosure delegate:abc
其中,delegate可以被设置为任意一个对象。
下面可以看下groovy中使用了setDelegate的应用:
Java代码
- 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()
输出:
Java代码
- doTestClosure this:test.Script@ffeef1
- doTestClosure owner:test.Script@ffeef1
- doTestClosure delegate:do test
- doTestClosure this:test.Script@ffeef1
- doTestClosure owner:test.Script@ffeef1
- doTestClosure delegate:1
可以看到,在通过metaClass动态添加方法时,delegate都被动态的设置为了调用者的实例本身,如上面的"do test"字符窜,以及整数1.
setDelegate还被广泛的使用于groovy builder的构建中。有兴趣的可以看下groovy中BuildSupport的实现。
以上是关于Groovy闭包中的this,owner和delegate的主要内容,如果未能解决你的问题,请参考以下文章
Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员赋值及源码分析 )
Groovy闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )
Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )