首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Groovy闭包中的this,owner跟delegate

2012-12-22 
Groovy闭包中的this,owner和delegate要想了解Groovy闭包中的this,owner和delegate的含义,首先我们需要知道

Groovy闭包中的this,owner和delegate

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

?

创建闭包的上下文

?

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

?

class Person{def static method(){def methodClosure={println "methodClosure this:"+thisprintln "methodClosure owner:"+ownerprintln "methodClosure delegate:"+delegate}methodClosure}}Person.method().call()
?

输出:

?

?

methodClosure this:class test.Person

methodClosure owner:class test.Person

methodClosure delegate:class test.Person

?

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

?

?

class Person{def static classClosure={println "classClosure this:"+thisprintln "classClosure owner:"+ownerprintln "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

?

?

def scriptClosure={println "scriptClosure this:"+thisprintln "scriptClosure owner:"+ownerprintln "scriptClosure delegate:"+delegate}scriptClosure.call()

?

输出:

?

?

scriptClosure this:test.Script@a09e41

scriptClosure owner:test.Script@a09e41

scriptClosure delegate:test.Script@a09e41

?

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

?

?

def closure={def closureClosure={println "closureClosure this:"+thisprintln "closureClosure owner:"+ownerprintln "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的含义也是不同的。

?

class ClosureTest{def static classClosure={println "classClosure this:"+thisprintln "classClosure owner:"+ownerprintln "classClosure delegate:"+delegate}def instanceClosure={println "instanceClosure this:"+thisprintln "instanceClosure owner:"+ownerprintln "instanceClosure delegate:"+delegate}def static classMethodClosure(){def classMethodClosure={println "classMethodClosure this:"+thisprintln "classMethodClosure owner:"+ownerprintln "classMethodClosure delegate:"+delegate}classMethodClosure.call()}def  instanceMethodClosure(){def instanceMethodClosure={println "instanceMethodClosure this:"+thisprintln "instanceMethodClosure owner:"+ownerprintln "instanceMethodClosure delegate:"+delegate}instanceMethodClosure.call()}}ClosureTest.classClosure()new ClosureTest().instanceClosure()ClosureTest.classMethodClosure()new ClosureTest().instanceMethodClosure()

?

输出:

?

classClosure this:class test.ClosureTestclassClosure owner:class test.ClosureTestclassClosure delegate:class test.ClosureTestinstanceClosure this:test.ClosureTest@11d3226instanceClosure owner:test.ClosureTest@11d3226instanceClosure delegate:test.ClosureTest@11d3226classMethodClosure this:class test.ClosureTestclassMethodClosure owner:class test.ClosureTestclassMethodClosure delegate:class test.ClosureTestinstanceMethodClosure this:test.ClosureTest@ecb3f1instanceMethodClosure owner:test.ClosureTest@ecb3f1instanceMethodClosure 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是指向定义它的闭包对象。 如上面最后一种创建上下文:

?

closureClosure owner:test.Script$_run_closure2@746ad0
?Delegate在闭包中的含义

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

?

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

?

?

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

?

输出:

?

?

before setDelegate()scriptClosure this:test.Script@67c1a6scriptClosure owner:test.Script@67c1a6scriptClosure delegate:test.Script@67c1a6after setDelegate()scriptClosure this:test.Script@67c1a6scriptClosure owner:test.Script@67c1a6scriptClosure delegate:abc

?

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

?

?

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

?

?

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

?

输出:

?

?

doTestClosure this:test.Script@ffeef1doTestClosure owner:test.Script@ffeef1doTestClosure delegate:do testdoTestClosure this:test.Script@ffeef1doTestClosure owner:test.Script@ffeef1doTestClosure delegate:1

?

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

?

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

?

?

热点排行