文章目录

  • 一、闭包的代理策略引入
  • 二、闭包的四种代理策略

一、闭包的代理策略引入


分别在 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 )相关推荐

  1. 【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )

    文章目录 一.闭包中调用 Groovy 脚本中的方法 二.owner 与 delegate 区别 三.闭包中调用 Groovy 对象中的方法 一.闭包中调用 Groovy 脚本中的方法 在 Groov ...

  2. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )

    文章目录 总结 一.静态闭包变量 1.执行普通闭包变量 2.执行静态闭包变量 二. 在闭包中定义闭包 三. 完整代码示例 总结 在闭包中 , 打印 this , owner , delegate , ...

  3. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )

    文章目录 总结 一.闭包类 Closure 简介 二.闭包类 Closure 中 this.owner.delegate 成员 源码分析 三.分析编译后的字节码文件内容 总结 在闭包中 , 打印 th ...

  4. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 )

    文章目录 一.闭包类 Closure 简介 二. 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 三. 完整代码示例 一.闭包类 Closure ...

  5. 【Groovy】闭包 Closure ( 闭包参数绑定 | curry 函数 | rcurry 函数 | ncurry 函数 | 代码示例 )

    文章目录 一.闭包参数绑定 1.闭包参数绑定 curry 函数 2.闭包参数绑定 rcurry 函数 3.闭包参数绑定 ncurry 函数 二.完整代码示例 一.闭包参数绑定 闭包 Closure 提 ...

  6. 【Groovy】闭包 Closure ( 闭包参数列表规则 | 默认参数列表 | 不接收参数 | 接收自定义参数 )

    文章目录 一.闭包参数列表 二.闭包参数列表代码示例 一.闭包参数列表 闭包的参数设置有如下情况 : 不接收参数 : 如果在定义闭包时 , 只写了 " -> " 符号 , 没 ...

  7. 【Groovy】闭包 Closure ( 闭包定义 | 闭包类型 | 查看编译后的字节码文件中的闭包类型变量 )

    文章目录 一.闭包定义 二.闭包类型 三.查看编译后的字节码文件中的闭包类型变量 一.闭包定义 闭包 Closure 是 Groovy 中最常用的特性 , 使用闭包作为参数是 Groovy 语言的明显 ...

  8. 【Groovy】闭包 Closure ( 闭包作为函数参数 | 代码示例 )

    文章目录 一.闭包作为函数参数 二.闭包作为函数参数代码示例 一.闭包作为函数参数 声明一个 fun 函数 , 可以 将参数声明为 Closure<?> 闭包类型 , 在该函数中 , 执行 ...

  9. 【Groovy】闭包 Closure ( 闭包调用 | 闭包默认参数 it | 代码示例 )

    文章目录 一.调用闭包 二.闭包默认参数 it 三.代码示例 一.调用闭包 执行 Closure 变量 的 call() 方法 , 可以调用该闭包 ; // 定义闭包变量def closure = { ...

最新文章

  1. 2020年全球程序员收入报告出炉,字节跳动成唯一上榜中国公司
  2. 常见的Java WEB服务器
  3. condest--1-范数的条件数估计
  4. common.logging和log4j比较
  5. 二分类卷积核极限数量实验
  6. 吴恩达深度学习课程deeplearning.ai课程作业:Class 1 Week 4 assignment4_1
  7. 【NLP-语义匹配】详解深度语义匹配模型DSSM
  8. java情书_Java情书已写好,就差妹子了!
  9. 高中计算机教师考试专业知识,高中教师资格证计算机专业考试内容
  10. 2017.9.13 序列统计 思考记录
  11. (转载)学习Javascript闭包(Closure)
  12. 2011最犀利语录大全
  13. python计算方位角_python实现两个经纬度点之间的距离和方位角
  14. Django笔记教程:三、Model进阶
  15. Python | 如何运行.ipynb文件?如何安装Jupyter notebook?
  16. ffmpeg用drawtext filter 给视频加字幕,代码实现
  17. java飞机英雄大战代码ppt_Java课程设计--飞机大战
  18. 127.0.0.1、0.0.0.0和本机IP地址的区别和使用
  19. hdu 2050折现分割平面
  20. html怎么搞一个微信图标,微信图标怎么点亮 两步搞定!

热门文章

  1. 成功网页设计师的七大必备技能
  2. 编写更好的CSS代码
  3. php中curl模拟post提交多维数组
  4. linux每天进步一点点-7月3日
  5. 使用ISA2004发布多个Web站点之二
  6. 路由器中的管理间距和量度参数
  7. 【转载】split / break polylines at point intersections
  8. 数学:拓展中国剩余定理
  9. nodeJs多线程 -- 学习记录
  10. GIT和SVN之间的五个基本区别