4

私はGroovyが初めてです。Groovy でクロージャがどのように実装されているのだろうか。

まあ言ってみれば :

def a = { println "Hello" }
a()

いつa()行われるのか、舞台裏で実際に何が起こっているのか? a()クロージャーを実行可能にするために呼び出すメソッドはどれですか?

前もって感謝します。

4

2 に答える 2

6

基本的に:

  • あなたのクロージャーは特定の名前のクラスです
  • a()呼び出すdoCall()呼び出し(クロージャでdoCall(Object it)暗黙的に)it
  • acallsiteメソッド名(2 x println)を含み、適切な引数で呼び出されます

どうぞ:

このGroovyスクリプトの場合:

def a = { println "Hello"; println "Hello2" }
a()

クロージャーaは次のようになります。

class Test$_run_closure1 extends Closure
implements GeneratedClosure
{

    public Object doCall(Object it)
    {
        CallSite acallsite[] = $getCallSiteArray();
        acallsite[0].callCurrent(this, "Hello");
        return acallsite[1].callCurrent(this, "Hello2");
    }

    public Object doCall()
    {
        CallSite acallsite[] = $getCallSiteArray();
        return doCall(null);
    }

    protected MetaClass $getStaticMetaClass()
    {
        if(getClass() != Test$_run_closure1)
            return ScriptBytecodeAdapter.initMetaClass(this);
        ClassInfo classinfo = $staticClassInfo;
        if(classinfo == null)
            $staticClassInfo = classinfo = ClassInfo.getClassInfo(getClass());
        return classinfo.getMetaClass();
    }

    public static void __$swapInit()
    {
        CallSite acallsite[] = $getCallSiteArray();
        $callSiteArray = null;
    }

    private static void $createCallSiteArray_1(String as[])
    {
        as[0] = "println";
        as[1] = "println";
    }

    private static CallSiteArray $createCallSiteArray()
    {
        String as[] = new String[2];
        $createCallSiteArray_1(as);
        return new CallSiteArray(Test$_run_closure1, as);
    }

    private static CallSite[] $getCallSiteArray()
    {
        CallSiteArray callsitearray;
        if($callSiteArray == null || (callsitearray = (CallSiteArray)$callSiteArray.get()) == null)
        {
            callsitearray = $createCallSiteArray();
            $callSiteArray = new SoftReference(callsitearray);
        }
        return callsitearray.array;
    }

    static Class _mthclass$(String s)
    {
        try
        {
            return Class.forName(s);
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }

    private static ClassInfo $staticClassInfo;
    public static transient boolean __$stMC;
    private static SoftReference $callSiteArray;

    static 
    {
        __$swapInit();
    }

    public Test$_run_closure1(Object _outerInstance, Object _thisObject)
    {
        CallSite acallsite[] = $getCallSiteArray();
        super(_outerInstance, _thisObject);
    }
}
于 2012-08-03T14:26:53.677 に答える
4

メソッドの 1 つを呼び出すことになりClosure.callます (この場合はargs のないメソッド) 。

ドキュメントにはこれに関する詳細情報があります

于 2012-08-03T13:25:43.140 に答える