概述
1. 闭包关键变量
闭包自带this,owner和delegate关键字。下面写一段测试代码,分别输出闭包这3个变量的值:
def testClouser = {
println "testClouser this:" + this
println "testClouser owner:" + owner
println "testClouser delegate:" + delegate
}
testClouser.call()
输出结果:
testClouser this:variable.variablestudy@662b4c69
testClouser owner:variable.variablestudy@662b4c69
testClouser delegate:variable.variablestudy@662b4c69
可以看到这3个变量输出的值是一样的。
this:表示闭包定义处的类
owner:表示闭包定义处的类或者对象
delegate:表示任意对象,有一个默认值和owner一致
下面多定义几个闭包,测试不同场景下3个参数所代表的的对象。
class Person {
def static classClouser = {
println "testClouser this:" + this
println "testClouser owner:" + owner
println "testClouser delegate:" + delegate
}
def static say() {
def classClouser = {
println "methodTestClouser this:" + this
println "methodTestClouser owner:" + owner
println "methodTestClouser delegate:" + delegate
}
classClouser.call()
}
}
Person.classClouser.call()
Person.say()
输出结果:
testClouser this:class variable.Person
testClouser owner:class variable.Person
testClouser delegate:class variable.Person
methodTestClouser this:class variable.Person
methodTestClouser owner:class variable.Person
methodTestClouser delegate:class variable.Person
输出结果指向的是类的字节码,不是具体的对象,是因为我们定义的都是static的闭包。
把代码中的static去掉:
class Person {
def classClouser = {
println "testClouser this:" + this
println "testClouser owner:" + owner
println "testClouser delegate:" + delegate
}
def say() {
def classClouser = {
println "methodTestClouser this:" + this
println "methodTestClouser owner:" + owner
println "methodTestClouser delegate:" + delegate
}
classClouser.call()
}
}
Person p = new Person()
p.classClouser.call()
p.say()
输出结果:
testClouser this:variable.Person@28f2a10f
testClouser owner:variable.Person@28f2a10f
testClouser delegate:variable.Person@28f2a10f
methodTestClouser this:variable.Person@28f2a10f
methodTestClouser owner:variable.Person@28f2a10f
methodTestClouser delegate:variable.Person@28f2a10f
这时候的输出就指向了Person具体对象。
这表明闭包对象this,owner,delegate默认指向最近的封闭类。
下面在闭包中定义闭包,看看这3个变量的值是否一样。
def nestClouser = {
def innerClouser = {
println "innerClouser this:" + this
println "innerClouser owner:" + owner
println "innerClouser delegate:" + delegate
}
innerClouser.call()
}
nestClouser.call()
输出结果:
innerClouser this:variable.variablestudy@28f2a10f
innerClouser owner:variable.variablestudy$_run_closure2@7205765b
innerClouser delegate:variable.variablestudy$_run_closure2@7205765b
可以看到,this指向了闭包定义处的类,owner和delegate一样,都指向了闭包。
如果在类或方法中定义闭包,this,owner,delegate3个变量的值是一样的。如果在闭包里面嵌套定义了闭包,this与owner和delegate的值就不一样了。this还会指向闭包定义处的类的实例或类本身。owner和delegate会指向最近的闭包对象。
那什么情况下owner和delegate会不同了,在代码中手动修改delegate的值:
class Person {
}
Person p = new Person()
def nestClouser = {
def innerClouser = {
println "innerClouser this:" + this
println "innerClouser owner:" + owner
println "innerClouser delegate:" + delegate
}
innerClouser.delegate = p
innerClouser.call()
}
nestClouser.call()
输出结果:
innerClouser this:variable.variablestudy@7133da86
innerClouser owner:variable.variablestudy$_run_closure2@20ccf40b
innerClouser delegate:variable.Person@2fb3536e
当认为修改delegate的值时,owner和delegate就会出现不一样的情况。
总结:
在大多数场景下,this,owner和delegate的值都是一样的。
在闭包中定义闭包时,this与owner和delegate的值不一样。
在修改闭包的delegate参数时,owner和delegate的值不一样。
this和owner是不可以修改的,delegate可以做做任意修改。
2. 闭包委托策略
先看一段简单的代码:
class Student {
String name
def pretty = {"My name is ${name}"}
String toString() {
pretty.call()
}
}
class Teacher {
String name
}
def stu = new Student(name : 'Sarash')
def tea = new Teacher(name : 'Teacher')
println stu.toString()
输出结果:
My name is Sarash
把上面代码的pretty闭包的delegate和resolveStrategy修改一下:
class Student {
String name
def pretty = {"My name is ${name}"}
String toString() {
pretty.call()
}
}
class Teacher {
String name
}
def stu = new Student(name : 'Sarash')
def tea = new Teacher(name : 'Teacher')
stu.pretty.delegate = tea
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString()
输出结果:
My name is Teacher
从结果可以看出闭包优先从tea查找变量,找到之后进行输出。
如果把Teacher的name改成其他命名,由于我们设置了Closure.DELEGATE_FIRST,它先从委托对象寻找,然后从owner对象寻找,最后在Student找到了name属性,进行输出。如果改成Closure.DELEGATE_ONLY,name在Teacher对象找不到name属性,代码会报错。
最后
以上就是野性灯泡为你收集整理的Groovy 闭包进阶1. 闭包关键变量2. 闭包委托策略的全部内容,希望文章能够帮你解决Groovy 闭包进阶1. 闭包关键变量2. 闭包委托策略所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复