Groovy闭包中的this,owner和delegate

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

 

创建闭包的上下文

 

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

 

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

 

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

 

 

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

 

 

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

 

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

 

 

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的含义也是不同的。

 

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()

 

输出:

 

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是指向定义它的闭包对象。 如上面最后一种创建上下文:

 

closureClosure owner:test.Script$_run_closure2@746ad0
 

Delegate在闭包中的含义

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

 

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

 

 

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: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的应用:

 

 

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: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的实现。

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值