Groovy闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )相关的知识,希望对你有一定的参考价值。
一、闭包的代理策略引入
分别在 Groovy 脚本 和 Test 类中定义 fun 方法 , 打印不同的内容 ;
在闭包 Closure 中分别调用上述两个方法 ,
代码示例 :
// I. 闭包中执行 Groovy 脚本中的方法
def fun()
println "fun"
def closure =
fun()
closure()
// II. 闭包中执行 Test 类中的方法
class Test
def fun()
println "fun2"
// 闭包中不能直接调用 Test 对象中的方法
// 此时可以通过改变闭包代理进行调用
def closure2 =
fun()
// 设置闭包的代理
closure2.delegate = new Test()
// 执行闭包
closure2()
上述代码执行结果 :
执行上述代码后 , 两个闭包都执行的是 Groovy 脚本中的 fun 方法 ;
即使 closure2 闭包设置的是 Test 实例对象作为代理 , 其仍然执行的是 Groovy 脚本中的 fun 方法 ;
// 设置闭包的代理
closure2.delegate = new Test()
这是因为 Closure 闭包的 代理策略问题导致的 ;
在 Closure 闭包中 , resolveStrategy 成员配置的是该闭包的代理策略 , 默认的代理策略 OWNER_FIRST , 也就是优先从 owner 中查找方法 ; 此时即使在 delegate 中有 fun 方法 , 也会被 owner 中的 fun 方法覆盖 ;
private int resolveStrategy = OWNER_FIRST;
二、闭包的四种代理策略
闭包的四种代理策略 :
- OWNER_FIRST : 所有者中的方法优先 ;
- DELEGATE_FIRST : 代理优先策略 , 代理中的方法优先 ;
- OWNER_ONLY : 只执行所有者中的方法 ;
- DELEGATE_ONLY : 只执行代理中的方法 ;
- TO_SELF : 只在自身查找 ;
public abstract class Closure<V> extends GroovyObjectSupport implements Cloneable, Runnable, GroovyCallable<V>, Serializable
/**
* 设置此resolveStrategy后,闭包将首先尝试将属性引用和方法解析给所有者,
* 然后是委托(<b>这是默认策略)。
*
* For example the following code :
* <pre>
* class Test
* def x = 30
* def y = 40
*
* def run()
* def data = [ x: 10, y: 20 ]
* def cl = y = x + y
* cl.delegate = data
* cl()
* println x
* println y
* println data
*
*
*
* new Test().run()
* </pre>
* will output :
* <pre>
* 30
* 70
* [x:10, y:20]
* </pre>
* 因为在测试类中声明的x和y字段在委托中定义了变量<p>
* <i>请注意,总是首先查找局部变量,而与解析策略无关。</i>
*/
public static final int OWNER_FIRST = 0;
/**
* 设置此resolveStrategy后,闭包将首先尝试将属性引用和方法解析为委托,然后解析为所有者。
*
* 例如,以下代码:
* <pre>
* class Test
* def x = 30
* def y = 40
*
* def run()
* def data = [ x: 10, y: 20 ]
* def cl = y = x + y
* cl.delegate = data
* cl.resolveStrategy = Closure.DELEGATE_FIRST
* cl()
* println x
* println y
* println data
*
*
*
* new Test().run()
* </pre>
* will output :
* <pre>
* 30
* 40
* [x:10, y:30]
* </pre>
* 因为在测试类中声明的x和y字段在委托中定义了变量<p>
* <i>请注意,总是首先查找局部变量,而与解析策略无关。</i>
*/
public static final int DELEGATE_FIRST = 1;
/**
* 使用此resolveStrategy集,闭包将只解析所有者的属性引用和方法,而不调用委托。
* 例如,以下代码:
*
* <pre>
* class Test
* def x = 30
* def y = 40
*
* def run()
* def data = [ x: 10, y: 20, z: 30 ]
* def cl = y = x + y + z
* cl.delegate = data
* cl.resolveStrategy = Closure.OWNER_ONLY
* cl()
* println x
* println y
* println data
*
*
*
* new Test().run()
* </pre>
*
* 将抛出“No-this-property:z”错误,因为即使在委托中声明了z变量,也不会进行查找<p>
* <i>请注意,总是首先查找局部变量,而与解析策略无关</我>
*/
public static final int OWNER_ONLY = 2;
/**
* 使用此resolveStrategy集,闭包将只解析委托的属性引用和方法,并完全绕过所有者。
* 例如,以下代码:
*
* <pre>
* class Test
* def x = 30
* def y = 40
* def z = 50
*
* def run()
* def data = [ x: 10, y: 20 ]
* def cl = y = x + y + z
* cl.delegate = data
* cl.resolveStrategy = Closure.DELEGATE_ONLY
* cl()
* println x
* println y
* println data
*
*
*
* new Test().run()
* </pre>
*
* 将引发错误,因为即使所有者声明了“z”字段,解析策略也将绕过所有者中的查找<p>
* <i>请注意,总是首先查找局部变量,而与解析策略无关</i>
*/
public static final int DELEGATE_ONLY = 3;
/**
* 使用此resolveStrategy集,闭包将解析自身的属性引用,
* 并执行通常的元类查找过程。
* 这意味着属性和方法既不能从所有者也不能从委托解析,
* 只能在闭包对象本身上解析。
* 这允许开发人员使用闭包本身的ExpandoMetaClass覆盖getProperty。<p>
* <i>请注意,总是首先查找局部变量,与解析策略无关。</i>
*/
public static final int TO_SELF = 4;
private int resolveStrategy = OWNER_FIRST;
以上是关于Groovy闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )的主要内容,如果未能解决你的问题,请参考以下文章
Groovy闭包 Closure ( 闭包调用 | 闭包默认参数 it | 代码示例 )
Groovy闭包 Closure ( 闭包作为函数参数 | 代码示例 )
Groovy闭包 Closure ( 闭包作为函数参数 | 代码示例 )
Groovy闭包 Closure ( 闭包定义 | 闭包类型 | 查看编译后的字节码文件中的闭包类型变量 )
Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员赋值及源码分析 )
Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )