Groovy闭包中的this,owner和delegate

Posted duangxcg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy闭包中的this,owner和delegate相关的知识,希望对你有一定的参考价值。

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

 

创建闭包的上下文

 

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

 

Java代码  
  1. class Person  
  2.       
  3.     def static method()  
  4.         def methodClosure=  
  5.             println "methodClosure this:"+this  
  6.             println "methodClosure owner:"+owner  
  7.             println "methodClosure delegate:"+delegate  
  8.           
  9.         methodClosure  
  10.       
  11.   
  12.   
  13. Person.method().call()  
 

输出:

 

 

methodClosure this:class test.Person

methodClosure owner:class test.Person

methodClosure delegate:class test.Person

 

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

 

 

Java代码  
  1. class Person  
  2.     def static classClosure=  
  3.         println "classClosure this:"+this  
  4.         println "classClosure owner:"+owner  
  5.         println "classClosure delegate:"+delegate  
  6.       
  7.   
  8.   
  9.   
  10. Person.classClosure.call()  
 

输出:

 

 

classClosure this:class test.Person

classClosure owner:class test.Person

classClosure delegate:class test.Person

 

再者,闭包可以在groovy的script中直接定义,实际上也是在类中直接定义,同上,因为groovy的script实际上会被编译为Script.class

 

 

Java代码  
  1. def scriptClosure=  
  2.     println "scriptClosure this:"+this  
  3.     println "scriptClosure owner:"+owner  
  4.     println "scriptClosure delegate:"+delegate  
  5.   
  6.   
  7. scriptClosure.call()  

 

输出:

 

 

scriptClosure this:test.Script@a09e41

scriptClosure owner:test.Script@a09e41

scriptClosure delegate:test.Script@a09e41

 

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

 

 

Java代码  
  1. def closure=  
  2.     def closureClosure=  
  3.         println "closureClosure this:"+this  
  4.         println "closureClosure owner:"+owner  
  5.         println "closureClosure delegate:"+delegate  
  6.       
  7.     closureClosure.call()  
  8.   
  9.   
  10. 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的含义也是不同的。

 

Java代码  
  1. class ClosureTest  
  2.     def static classClosure=  
  3.         println "classClosure this:"+this  
  4.         println "classClosure owner:"+owner  
  5.         println "classClosure delegate:"+delegate  
  6.       
  7.       
  8.     def instanceClosure=  
  9.         println "instanceClosure this:"+this  
  10.         println "instanceClosure owner:"+owner  
  11.         println "instanceClosure delegate:"+delegate  
  12.       
  13.       
  14.     def static classMethodClosure()  
  15.         def classMethodClosure=  
  16.             println "classMethodClosure this:"+this  
  17.             println "classMethodClosure owner:"+owner  
  18.             println "classMethodClosure delegate:"+delegate  
  19.           
  20.         classMethodClosure.call()  
  21.       
  22.       
  23.     def  instanceMethodClosure()  
  24.         def instanceMethodClosure=  
  25.             println "instanceMethodClosure this:"+this  
  26.             println "instanceMethodClosure owner:"+owner  
  27.             println "instanceMethodClosure delegate:"+delegate  
  28.           
  29.         instanceMethodClosure.call()  
  30.       
  31.   
  32.   
  33. ClosureTest.classClosure()  
  34. new ClosureTest().instanceClosure()  
  35. ClosureTest.classMethodClosure()  
  36. new ClosureTest().instanceMethodClosure()  

 

输出:

 

Java代码  
  1. classClosure this:class test.ClosureTest  
  2. classClosure owner:class test.ClosureTest  
  3. classClosure delegate:class test.ClosureTest  
  4. instanceClosure this:test.ClosureTest@11d3226  
  5. instanceClosure owner:test.ClosureTest@11d3226  
  6. instanceClosure delegate:test.ClosureTest@11d3226  
  7. classMethodClosure this:class test.ClosureTest  
  8. classMethodClosure owner:class test.ClosureTest  
  9. classMethodClosure delegate:class test.ClosureTest  
  10. instanceMethodClosure this:test.ClosureTest@ecb3f1  
  11. instanceMethodClosure owner:test.ClosureTest@ecb3f1  
  12. 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是指向定义它的闭包对象。 如上面最后一种创建上下文:

 

Java代码  
  1. closureClosure owner:test.Script$_run_closure2@746ad0  
 

Delegate在闭包中的含义

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

 

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

 

 

Java代码  
  1. def scriptClosure=  
  2.     println "scriptClosure this:"+this  
  3.     println "scriptClosure owner:"+owner  
  4.     println "scriptClosure delegate:"+delegate  
  5.   
  6. println "before setDelegate()"  
  7. scriptClosure.call()  
  8. scriptClosure.setDelegate ("abc")  
  9. println "after setDelegate()"  
  10. scriptClosure.call()  
 

 

输出:

 

 

Java代码  
  1. before setDelegate()  
  2. scriptClosure this:test.Script@67c1a6  
  3. scriptClosure owner:test.Script@67c1a6  
  4. scriptClosure delegate:test.Script@67c1a6  
  5. after setDelegate()  
  6. scriptClosure this:test.Script@67c1a6  
  7. scriptClosure owner:test.Script@67c1a6  
  8. scriptClosure delegate:abc  

 

其中,delegate可以被设置为任意一个对象。

 

 

下面可以看下groovy中使用了setDelegate的应用:

 

 

Java代码  
  1. String.metaClass.doTestClosure=  
  2.     println "doTestClosure this:"+this  
  3.     println "doTestClosure owner:"+owner  
  4.     println "doTestClosure delegate:"+delegate  
  5.   
  6. "do test".doTestClosure()  
  7.   
  8.   
  9. Integer.metaClass.doTestClosure=  
  10.     println "doTestClosure this:"+this  
  11.     println "doTestClosure owner:"+owner  
  12.     println "doTestClosure delegate:"+delegate  
  13.   
  14. 1.doTestClosure()  

 

输出:

 

 

Java代码  
  1. doTestClosure this:test.Script@ffeef1  
  2. doTestClosure owner:test.Script@ffeef1  
  3. doTestClosure delegate:do test  
  4. doTestClosure this:test.Script@ffeef1  
  5. doTestClosure owner:test.Script@ffeef1  
  6. doTestClosure delegate:1  

 

可以看到,在通过metaClass动态添加方法时,delegate都被动态的设置为了调用者的实例本身,如上面的"do test"字符窜,以及整数1. 

 

setDelegate还被广泛的使用于groovy builder的构建中。有兴趣的可以看下groovy中BuildSupport的实现。

 

以上是关于Groovy闭包中的this,owner和delegate的主要内容,如果未能解决你的问题,请参考以下文章

Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员赋值及源码分析 )

Groovy闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )

Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )

Gradle语法之再解闭包

groovy 中的闭包与 java 8 中的闭包(lambda 表达式)?

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