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

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )相关的知识,希望对你有一定的参考价值。

总结


在闭包中 , 打印 this , owner , delegate , 打印结果都是创建闭包时所在的类 ;

  • 如果在类中创建闭包 , 则打印结果是类 ;
  • 如果在实例对象中创建闭包 , 则打印结果是实例对象 ;
  • 如果在闭包 A 中创建 闭包 B , this 是最外层闭包 A 之外的类 , owner , delegate 是上一层闭包 B ;




一、静态闭包变量




1、执行普通闭包变量


在类中定义闭包变量 , 在闭包中打印 this、owner、delegate 值 ,

class Test2 
    def closure = 
        println "this : " + this
        println "owner : " + owner
        println "delegate : " + delegate
    

执行上述 Test2 类中的闭包 ,

new Test2().closure()

打印结果如下 : 打印的值都是 Test2 实例对象 ;

this : Test2@5082d622
owner : Test2@5082d622
delegate : Test2@5082d622

2、执行静态闭包变量


如果将闭包声明为静态变量 ,

class Test2 
    def static closure = 
        println "this : " + this
        println "owner : " + owner
        println "delegate : " + delegate
    

直接使用闭包所在类直接调用闭包 , 不再使用闭包所在类对象调用闭包 ;

Test2.closure()

执行结果为 : 打印的值都是 Test2 类 ;

this : class Test2
owner : class Test2
delegate : class Test2

还是上述静态闭包变量 , 使用 Test2 实例对象调用 ,

new Test2().closure()

打印的结果是创建闭包时所在的类 ;

this : class Test2
owner : class Test2
delegate : class Test2




二、 在闭包中定义闭包



在 Test2 类中定义 闭包变量 closure2 , 在 closure2 闭包中定义 closure3 闭包 ,

class Test2 
    def closure2 = 
        def closure3 = 
            println "this : " + this
            println "owner : " + owner
            println "delegate : " + delegate
        
        closure3()
    

打印结果如下 :

this : Test2@291a7e3c
owner : Test2$_closure1@4ae9cfc1
delegate : Test2$_closure1@4ae9cfc1

this 值为 外部的 Test2 实例对象 ;

owner 和 delegate 是 Test2 中定义的 closure2 闭包 ;


创建 closure2 闭包时 , this、owner、delegate 都是 Test2 实例对象 ;

但是创建 closure3 闭包时 , this 的值还是设置 closure2 的 this 值 , owner、delegate 值设置成 closure2 闭包 ;

			// 创建内层闭包时 , 传入的 this 是 外层闭包的 this.getThisObject() 
			// 因此 this 值仍是 Test2 实例对象 
			// owner、delegate 变为外层的 Closure 闭包 ; 
            Object closure3 = new _closure2(this, this.getThisObject());

分析生成的字节码文件 :

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import groovy.lang.Closure;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class Test2 implements GroovyObject 
    private Object closure2;

    @Generated
    public Test2() 
        CallSite[] var1 = $getCallSiteArray();
        super();
        // 创建外层闭包 
        Test2._closure1 var2 = new Test2._closure1(this, this);
        this.closure2 = var2;
        MetaClass var3 = this.$getStaticMetaClass();
        this.metaClass = var3;
    

    @Generated
    @Internal
    public MetaClass getMetaClass() 
        MetaClass var10000 = this.metaClass;
        if (var10000 != null) 
            return var10000;
         else 
            this.metaClass = this.$getStaticMetaClass();
            return this.metaClass;
        
    

    @Generated
    @Internal
    public void setMetaClass(MetaClass var1) 
        this.metaClass = var1;
    

    @Generated
    public Object getClosure2() 
        return this.closure2;
    

    @Generated
    public void setClosure2(Object var1) 
        this.closure2 = var1;
    

	// 这是外层的 Closure 闭包
    public final class _closure1 extends Closure implements GeneratedClosure 
        public _closure1(Object _outerInstance, Object _thisObject) 
            CallSite[] var3 = $getCallSiteArray();
            super(_outerInstance, _thisObject);
        

        public Object doCall(Object it) 
            CallSite[] var2 = $getCallSiteArray();

			// 这是内层的 Closure 闭包
            final class _closure2 extends Closure implements GeneratedClosure 
                public _closure2(Object _outerInstance, Object _thisObject) 
                    CallSite[] var3 = $getCallSiteArray();
                    super(_outerInstance, _thisObject);
                

                public Object doCall(Object it) 
                    CallSite[] var2 = $getCallSiteArray();
                    var2[0].callCurrent(this, var2[1].call("this : ", this.getThisObject()));
                    var2[2].callCurrent(this, var2[3].call("owner : ", var2[4].callGroovyObjectGetProperty(this)));
                    return var2[5].callCurrent(this, var2[6].call("delegate : ", var2[7].callGroovyObjectGetProperty(this)));
                

                @Generated
                public Object doCall() 
                    CallSite[] var1 = $getCallSiteArray();
                    return this.doCall((Object)null);
                
            

			// 创建内层闭包时 , 传入的 this 是 外层闭包的 this.getThisObject() 
			// 因此 this 值仍是 Test2 实例对象 
			// owner、delegate 变为外层的 Closure 闭包 ; 
            Object closure3 = new _closure2(this, this.getThisObject());
            return var2[0].call(closure3);
        

        @Generated
        public Object doCall() 
            CallSite[] var1 = $getCallSiteArray();
            return this.doCall((Object)null);
        
    






三、 完整代码示例



完整代码示例 :

class Test2 
    // 定义静态闭包
    // 即可以通过类执行
    // 又可以通过对象执行
    def static closure = 
        println "this : " + this
        println "owner : " + owner
        println "delegate : " + delegate
    

    // 闭包中定义闭包
    def closure2 = 
        def closure3 = 
            println "this : " + this
            println "owner : " + owner
            println "delegate : " + delegate
        
        closure3()
    


println "通过类执行闭包 :"

Test2.closure()

println "\\n通过对象执行闭包 :"

new Test2().closure()

println "\\n闭包中定义闭包并执行 : "

new Test2().closure2()


执行结果 :

通过类执行闭包 :
this : class Test2
owner : class Test2
delegate : class Test2

通过对象执行闭包 :
this : class Test2
owner : class Test2
delegate : class Test2

闭包中定义闭包并执行 : 
this : Test2@1f010bf0
owner : Test2$_closure1@40db2a24
delegate : Test2$_closure1@40db2a24

以上是关于Groovy闭包 Closure ( 闭包类 Closure 简介 | thisownerdelegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

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

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