一个简单的groovy script生成的class文件及其反编译

Groovy

def task = {
	println "Hello from source code-Task"
	}
task()

def task2 = {
	println "Hello from source code-Task2"
	}
	
class B {
	String getName(){
		return "Young"
	}
}

println new B().getName();

task2();

结果

Hello from source code-Task
Young
Hello from source code-Task2

Groovy默认是不为这个script写class文件的,但是我们可以通过配置文件或者直接修改原码, 

conf.setTargetDirectory

指定class的存放路径

这里生成四个class文件

B.class  test$_run_closure1, test$_run_closure2.class, test.class

反编译以后

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class B
  implements GroovyObject
{
  public B()
  {
    B this;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    MetaClass localMetaClass = $getStaticMetaClass();
    this.metaClass = localMetaClass;
  }
  
  public String getName()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return "Young";return null;
  }
  
  static
  {
    __$swapInit();
    Long localLong1 = Long.valueOf(0L);
    __timeStamp__239_neverHappen1423373575093 = localLong1.longValue();
    Long localLong2 = Long.valueOf(1423373575093L);
    __timeStamp = localLong2.longValue();
  }
}


import groovy.lang.Closure;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;

class test$_run_closure1
  extends Closure
  implements GeneratedClosure
{
  public test$_run_closure1(Object _outerInstance, Object _thisObject)
  {
    super(_outerInstance, _thisObject);
  }
  
  public Object doCall(Object it)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task");return null;
  }
  
  public Object doCall()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    return doCall(null);
    return null;
  }
  
  static {}
}

import groovy.lang.Closure;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;

class test$_run_closure2
  extends Closure
  implements GeneratedClosure
{
  public test$_run_closure2(Object _outerInstance, Object _thisObject)
  {
    super(_outerInstance, _thisObject);
  }
  
  public Object doCall(Object it)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task2");return null;
  }
  
  public Object doCall()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    return doCall(null);
    return null;
  }
  
  static {}
}

import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class test
  extends Script
{
  public test()
  {
    test this;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
  }
  
  public test(Binding arg1)
  {
    Binding context;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    ScriptBytecodeAdapter.invokeMethodOnSuperN(Script.class, this, "setBinding", new Object[] { context });
  }
  
  public static void main(String... args)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    arrayOfCallSite[0].call(InvokerHelper.class, test.class, args);
  }
  
  class _run_closure1
    extends Closure
    implements GeneratedClosure
  {
    public _run_closure1(Object _thisObject)
    {
      super(_thisObject);
    }
    
    public Object doCall(Object it)
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task");return null;
    }
    
    public Object doCall()
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();
      return doCall(null);
      return null;
    }
    
    static {}
  }
  
  class _run_closure2
    extends Closure
    implements GeneratedClosure
  {
    public _run_closure2(Object _thisObject)
    {
      super(_thisObject);
    }
    
    public Object doCall(Object it)
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task2");return null;
    }
    
    public Object doCall()
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();
      return doCall(null);
      return null;
    }
    
    static {}
  }
  
  public Object run()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();Object task = new test._run_closure1(this);
    

    arrayOfCallSite[1].call(task);
    
    Object task2 = new test._run_closure2(this);
    








    arrayOfCallSite[2].callCurrent(this, arrayOfCallSite[3].call(arrayOfCallSite[4].callConstructor(B.class)));
    
    return arrayOfCallSite[5].call(task2);return null;
  }
  
  static
  {
    __$swapInit();
    Long localLong1 = Long.valueOf(0L);
    __timeStamp__239_neverHappen1423373575421 = localLong1.longValue();
    Long localLong2 = Long.valueOf(1423373575421L);
    __timeStamp = localLong2.longValue();
  }
}

核心的执行代码是

script = (Script) scriptClass.newInstance();        ---->1

script.run(); ----->2


执行1的时候

首先执行了一个内布生成的createCallSiteArray 函数,它会执行

    public CallSiteArray(Class owner, String [] names) {
        this.owner = owner;
        array = new CallSite[names.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = new AbstractCallSite(this, i, names[i]);
        }
    }

owner = class<T> test

names = [runScript, call, println, getName, <$constructor$>, call]


接下来执行Script的构造函数

接着执行2的时候

1 test$_run_closure1.$createCallSiteArray     owner = class test$_run_closure1,   names=[println]

2. Closure的构造函数  owner = test , thisObject=test

    public Closure(Object owner, Object thisObject) {
        this.owner = owner;
        this.delegate = owner;
        this.thisObject = thisObject;

...

}

3.   走到test.groovy的 task()处

调用 AbstractCallSite.java        receiver = test$_run_closure1

public Object call(Object receiver) throws Throwable {
        return call(receiver, CallSiteArray.NOPARAM);
    }

->

    public Object call(Object receiver, Object[] args) throws Throwable {
        return CallSiteArray.defaultCall(this, receiver, args);
    }

->

CallSiteArray.java

    public static Object defaultCall(CallSite callSite, Object receiver, Object[] args) throws Throwable {
        return createCallSite(callSite, receiver, args).call(receiver, args);
    }

//createCallSite will return an PogoMetaClassSite object, which is also subclass of AbstractCallSite

->

MetaMethod.java

public Object doMethodInvoke(Object object, Object[] argumentArray)

->很奇怪的调用堆栈

    public Object callCurrent(GroovyObject receiver, Object arg1) throws Throwable {
        return callCurrent(receiver, ArrayUtil.createArray(arg1));
    }

//receiver = test$_run_closure1@186062a

//arg1 = "Hello from source code-Task"


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值