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"