当前位置:网站首页>[groovy] closure (Introduction to closure class closure | this, owner, delegate member assignment and source code analysis)

[groovy] closure (Introduction to closure class closure | this, owner, delegate member assignment and source code analysis)

2022-07-05 04:40:00 Programmer community

List of articles

  • summary
  • One 、 Closure class Closure brief introduction
  • Two 、 Closure class Closure in this、owner、delegate member Source code analysis
  • 3、 ... and 、 Analyze the contents of the compiled bytecode file

summary

In closure , Print this , owner , delegate , The printing results are the class where the closure is located ;

One 、 Closure class Closure brief introduction


In closure Closure There is

3

3

3 Members , this , owner , delegate , Print this in the closure

3

3

3 Members ,

def closure = { 
        println "this : ${this}"    println "owner : ${owner}"    println "delegate : ${delegate}"}

Execute closure call() Method , Or use it directly Closure () Execute closure ;

closure()

The results are as follows , What is printed is the closure object ;

this : Groovy@5c45d770owner : Groovy@5c45d770delegate : Groovy@5c45d770

Groovy.groovy The bytecode file after code compilation is Groovy.class , among

Two 、 Closure class Closure in this、owner、delegate member Source code analysis


Closure class Closure Medium delegate , owner , thisObject The members are as follows , In the constructor , by Object owner, Object thisObject this

2

2

2 Member assignments ;

In closure , visit owner , It's actually a call getOwner function , visit delegate It's actually a call getDelegate function , this Namely thisObject ;

Particular attention , In the constructor , For this

3

3

3 Members are assigned ;

Closure class Closure in this、owner、delegate member Source code :

public abstract class Closure<V> 		extends GroovyObjectSupport 		implements Cloneable, Runnable, GroovyCallable<V>, Serializable { 
        private Object delegate;    private Object owner;    private Object thisObject;	//  Closure constructor      public Closure(Object owner, Object thisObject) { 
            this.owner = owner;        this.delegate = owner;        this.thisObject = thisObject;        final CachedClosureClass cachedClass =         	(CachedClosureClass) ReflectionCache.getCachedClass(getClass());        parameterTypes = cachedClass.getParameterTypes();        maximumNumberOfParameters = cachedClass.getMaximumNumberOfParameters();    }    /** * @return  The owner object to which the method call will go , It is usually the external class when constructing closures  */    public Object getOwner() { 
            return this.owner;    }    /** * @return  When constructing closures , The delegate object to which the method call will go is usually an external class  */    public Object getDelegate() { 
            return this.delegate;    }}

3、 ... and 、 Analyze the contents of the compiled bytecode file


see Groovy Bytecode file after code compilation Groovy.class ,

public class Groovy extends Script

 Insert picture description here

In the compiled bytecode file , Declared closure variables

def closure = { 
        println "this : ${this}"    println "owner : ${owner}"    println "delegate : ${delegate}"}

The generated corresponding closure class is :

final class _run_closure1 extends Closure implements GeneratedClosure

The constructor of this closure class is in public class Groovy extends Script Medium run Call in method , take Groovy The instance object is passed into the closure constructor ;

		//  Create closures  ,  Incoming parameter  this  yes  class Groovy extends Script  Class instance object          Object closure = new _run_closure1(this, this);

In the constructor of closure class , Constructor of parent class called , Separately _outerInstance Assign a value to owner member , take _thisObject Assign a value to thisObject member , and _thisObject and _outerInstance Parameters are this , namely Groovy Script generation class , class Groovy extends Script ;

        	//  Closure constructor              public _run_closure1(Object _outerInstance, Object _thisObject) { 
                    CallSite[] var3 = $getCallSiteArray();                //  The constructor of the parent class is called here  ,  , respectively,                 //  take  _outerInstance  Assign a value to  owner  member                 //  take  _thisObject  Assign a value to  thisObject  member                  //  and  _thisObject  and  _outerInstance  Parameters are  this                 //  namely  Groovy  Script generation class  , class Groovy extends Script                super(_outerInstance, _thisObject);            }

The contents of the compiled bytecode are as follows :

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//import groovy.lang.Binding;import groovy.lang.Closure;import groovy.lang.Script;import groovy.transform.Generated;import org.codehaus.groovy.runtime.GStringImpl;import org.codehaus.groovy.runtime.GeneratedClosure;import org.codehaus.groovy.runtime.InvokerHelper;import org.codehaus.groovy.runtime.callsite.CallSite;public class Groovy extends Script { 
        public Groovy() { 
            CallSite[] var1 = $getCallSiteArray();        super();    }    public Groovy(Binding context) { 
            CallSite[] var2 = $getCallSiteArray();        super(context);    }    public static void main(String... args) { 
            CallSite[] var1 = $getCallSiteArray();        var1[0].call(InvokerHelper.class, Groovy.class, args);    }    public Object run() { 
            CallSite[] var1 = $getCallSiteArray();		//  Closure class         final class _run_closure1 extends Closure implements GeneratedClosure { 
            	//  Closure constructor              public _run_closure1(Object _outerInstance, Object _thisObject) { 
                    CallSite[] var3 = $getCallSiteArray();                //  The constructor of the parent class is called here  ,  , respectively,                 //  take  _outerInstance  Assign a value to  owner  member                 //  take  _thisObject  Assign a value to  thisObject  member                  //  and  _thisObject  and  _outerInstance  Parameters are  this                 //  namely  Groovy  Script generation class  , class Groovy extends Script                super(_outerInstance, _thisObject);            }            			//  Call closure             public Object doCall(Object it) { 
                    CallSite[] var2 = $getCallSiteArray();                var2[0].callCurrent(this, new GStringImpl(new Object[]{ 
    this.getThisObject()}, new String[]{ 
    "this : ", ""}));                var2[1].callCurrent(this, new GStringImpl(new Object[]{ 
    var2[2].callGroovyObjectGetProperty(this)}, new String[]{ 
    "owner : ", ""}));                return var2[3].callCurrent(this, new GStringImpl(new Object[]{ 
    var2[4].callGroovyObjectGetProperty(this)}, new String[]{ 
    "delegate : ", ""}));            }			//  Call closure              @Generated            public Object doCall() { 
                    CallSite[] var1 = $getCallSiteArray();                return this.doCall((Object)null);            }        }		//  Create closures  ,  Incoming parameter  this  yes  class Groovy extends Script  Class instance object          Object closure = new _run_closure1(this, this);        return var1[1].call(closure);    }}

原网站

版权声明
本文为[Programmer community]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140632099894.html