public Object doCall(Object it) {
CallSite[] var2 = $getCallSiteArray();
Object var10000 = var2[0].call(testStr.get(), it);
testStr.set(var10000);
return var10000;
}
public Object getTestStr() {
CallSite[] var1 = $getCallSiteArray();
return testStr.get();
}
@Generated
public Object doCall() {
CallSite[] var1 = $getCallSiteArray();
return this.doCall((Object)null);
}
}
//range的翻译
var1[1].call(ScriptBytecodeAdapter.createRange(1, 10, (boolean)1), new _run_closure1(this, this));
return var1[2].callCurrent(this, testStr.get());
}
}
上面代码不用看懂所有,也没有必要,你只要领悟精髓即可,即 Groovy 的一切都是对象,闭包的本质就是 Closure 实例对象即可,其他都可以理解成是 Java 的一种拓展,你甚至可以理解成他就是 Java 的一个三方框架,只是这个框架不仅仅提供了代码编写的规范,还有自己的一套构建规则,这才是本质思想。
闭包的委托策略
渐渐的我们慢慢揭开了闭包的面纱,Groovy 的闭包有委托的概念,即在闭包中修改委托对象和委托策略的能力,能够让它在 DSL(Domain Specific Languages)领域(譬如 Gradle 等)得到升华。理解闭包的委托功能,就需要先弄明白groovy.lang.Closure
类的三个属性,即 this、owner 和 delegate。
this、owner 和 delegate
this: 指向定义闭包所在的封闭类。在闭包中可以通过getThisObject()
方法获取定义闭包的封闭类,和显式调用 this 是等价的效果。这个不用再举例子了,比较简单,可以看下一小节的案例。
owner: 对应定义声明闭包的封闭对象,可以是类或者闭包。它与 this 有点类似,最大的不同是 owner 指向的是直接包裹它的对象(普通对象或者闭包对象)。这个不用再举例子了,比较简单,可以看下一小节的案例。
delegate: 可以对应任何对象。this 和 owner 都属于闭包的标准语法范围,而 delegate 指向的是闭包所使用的用户自定义的对象。默认情况下 delegate 被设置成 owner。我们可以通过 delegate 关键字和getDelegate()
、setDelegate(x)
方法来使用委托对象。样例如下:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
class Animal {
String name
}
class Cat {
String name
}
def dog = new Animal(name: ‘dog’)
def cat = new Cat(name: ‘catter’)
def nameLength = { delegate.name.length() }
/**
-
默认 delegate 等价于 owner,即声明闭包所属的对象,此处为 Script
-
所以运行直接报错,因为 delegate 指向的对象没有 name 属性
*/
println(nameLength())
/**
-
闭包 delegate 指向 dog 对象
-
所以运行打印为 3
*/
nameLength.delegate = dog
println(nameLength())
/**
-
闭包 delegate 指向 cat 对象
-
所以运行打印为 6
*/
nameLength.delegate = cat
println(nameLength())
深入委托策略
在 Java 类的实例方法中调用类的方法和引用属性时,我们可以省略方法或属性前的this
(譬如this.func()
、this.property
可简写为func()
和property
),表示调用或引用的是本实例的方法或属性。
这个特性在 Groovy 中同样适用,而且 Groovy 在 闭包 Closure 中调用方法和引用属性时,我们也可以省略方法和属性前的delegate
(譬如delegate.func()
、delegate.property
可简写为func()
和property
),表示调用或引用的是本闭包的方法或属性(而闭包 Closure 通过 delegate 隐式变量将方法调用和变量引用委派给了 delegate 引用的那个对象)。
闭包 delegate 的默认值是 Closure 的隐式变量 owner,而 owner 通常对应定义声明闭包的封闭对象,可以是类或者闭包。因此,无论什么时候,在闭包中访问某个属性时如果没有明确地设置接收者对象,那么就会调用一个委托策略,譬如如下案例:
class ClosureTest {
String str1 = “1”
def outerClosure = {
def str2 = “2”
/**
-
属性或者方法存在于 owner 内,那么他可以被 owner 调用