Groovy初探

  1. 先写一个java代码
//   ./java/MyClass.java
public class MyClass {
    public int add() {
        int a = 1;
        int b = 2;
        return a+b;
    }
    public static void main(String[] args) {
        MyClass m = new MyClass();
        System.out.println(m.add());
    }
}
  1. 编译java源文件
javac MyClass.java
  1. 查看字节码
javap -c MyClass >MyClass.txt

输出

Compiled from "MyClass.java"
public class MyClass {
  public MyClass();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int add();
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: new           #7                  // class MyClass
       3: dup
       4: invokespecial #9                  // Method "<init>":()V
       7: astore_1
       8: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: aload_1
      12: invokevirtual #16                 // Method add:()I
      15: invokevirtual #20                 // Method java/io/PrintStream.println:(I)V
      18: return
}
  1. 直接将java源文件改成groovy
cp java/MyClass.java groovy/MyClass.groovy
  1. 编译groovy源文件
groovyc MyClass.groovy
  1. 查看字节码
javap -c MyClass >MyClass.txt

输出结果

Compiled from "MyClass.groovy"
public class MyClass implements groovy.lang.GroovyObject {
  public static transient boolean __$stMC;

  public MyClass();
    Code:
       0: nop
       1: invokestatic  #20                 // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
       4: astore_1
       5: aload_0
       6: invokespecial #22                 // Method java/lang/Object."<init>":()V
       9: aload_0
      10: invokevirtual #26                 // Method $getStaticMetaClass:()Lgroovy/lang/MetaClass;
      13: astore_2
      14: aload_2
      15: aload_0
      16: swap
      17: putfield      #28                 // Field metaClass:Lgroovy/lang/MetaClass;
      20: aload_2
      21: pop
      22: return

  public int add();
    Code:
       0: nop
       1: invokestatic  #20                 // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
       4: astore_1
       5: iconst_1
       6: istore_2
       7: iload_2
       8: pop
       9: iconst_2
      10: istore_3
      11: iload_3
      12: pop
      13: invokestatic  #38                 // Method org/codehaus/groovy/runtime/BytecodeInterface8.isOrigInt:()Z
      16: ifeq          34
      19: getstatic     #40                 // Field __$stMC:Z
      22: ifne          34
      25: invokestatic  #43                 // Method org/codehaus/groovy/runtime/BytecodeInterface8.disabledStandardMetaClass:()Z
      28: ifne          34
      31: goto          58
      34: aload_1
      35: ldc           #44                 // int 0
      37: aaload
      38: iload_2
      39: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      42: iload_3
      43: invokestatic  #50                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      46: invokeinterface #56,  3           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      51: invokestatic  #62                 // Method org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.intUnbox:(Ljava/lang/Object;)I
      54: ireturn
      55: nop
      56: nop
      57: athrow
      58: iload_2
      59: iload_3
      60: iadd
      61: ireturn

  public static void main(java.lang.String...);
    Code:
       0: nop
       1: invokestatic  #20                 // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
       4: astore_1
       5: aload_1
       6: ldc           #72                 // int 1
       8: aaload
       9: ldc           #2                  // class MyClass
      11: invokeinterface #76,  2           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callConstructor:(Ljava/lang/Object;)Ljava/lang/Object;
      16: ldc           #2                  // class MyClass
      18: invokestatic  #82                 // Method org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
      21: checkcast     #2                  // class MyClass
      24: astore_2
      25: aload_2
      26: pop
      27: aload_1
      28: ldc           #83                 // int 2
      30: aaload
      31: aload_1
      32: ldc           #84                 // int 3
      34: aaload
      35: ldc           #86                 // class java/lang/System
      37: invokeinterface #89,  2           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callGetProperty:(Ljava/lang/Object;)Ljava/lang/Object;
      42: aload_1
      43: ldc           #90                 // int 4
      45: aaload
      46: aload_2
      47: invokeinterface #92,  2           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;)Ljava/lang/Object;
      52: invokeinterface #56,  3           // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
      57: pop
      58: return

  protected groovy.lang.MetaClass $getStaticMetaClass();
    Code:
       0: aload_0
       1: invokevirtual #99                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
       4: ldc           #2                  // class MyClass
       6: if_acmpeq     14
       9: aload_0
      10: invokestatic  #103                // Method org/codehaus/groovy/runtime/ScriptBytecodeAdapter.initMetaClass:(Ljava/lang/Object;)Lgroovy/lang/MetaClass;
      13: areturn
      14: getstatic     #105                // Field $staticClassInfo:Lorg/codehaus/groovy/reflection/ClassInfo;
      17: astore_1
      18: aload_1
      19: ifnonnull     34
      22: aload_0
      23: invokevirtual #99                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
      26: invokestatic  #111                // Method org/codehaus/groovy/reflection/ClassInfo.getClassInfo:(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;
      29: dup
      30: astore_1
      31: putstatic     #105                // Field $staticClassInfo:Lorg/codehaus/groovy/reflection/ClassInfo;
      34: aload_1
      35: invokevirtual #114                // Method org/codehaus/groovy/reflection/ClassInfo.getMetaClass:()Lgroovy/lang/MetaClass;
      38: areturn

  public groovy.lang.MetaClass getMetaClass();
    Code:
       0: aload_0
       1: getfield      #28                 // Field metaClass:Lgroovy/lang/MetaClass;
       4: dup
       5: ifnull        9
       8: areturn
       9: pop
      10: aload_0
      11: dup
      12: invokevirtual #26                 // Method $getStaticMetaClass:()Lgroovy/lang/MetaClass;
      15: putfield      #28                 // Field metaClass:Lgroovy/lang/MetaClass;
      18: aload_0
      19: getfield      #28                 // Field metaClass:Lgroovy/lang/MetaClass;
      22: areturn

  public void setMetaClass(groovy.lang.MetaClass);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #28                 // Field metaClass:Lgroovy/lang/MetaClass;
       5: return
}
  1. 反编译字节码
java -jar cfr-0.151.jar ./groovy/MyClass.class  --outputpath ./groovy

输出结果

/*
 * Decompiled with CFR 0.151.
 * 
 * Could not load the following classes:
 *  groovy.lang.GroovyObject
 *  groovy.lang.MetaClass
 *  groovy.transform.Generated
 *  groovy.transform.Internal
 *  org.codehaus.groovy.reflection.ClassInfo
 *  org.codehaus.groovy.runtime.BytecodeInterface8
 *  org.codehaus.groovy.runtime.ScriptBytecodeAdapter
 *  org.codehaus.groovy.runtime.callsite.CallSite
 *  org.codehaus.groovy.runtime.callsite.CallSiteArray
 *  org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation
 */
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import java.beans.Transient;
import java.lang.ref.SoftReference;
import org.codehaus.groovy.reflection.ClassInfo;
import org.codehaus.groovy.runtime.BytecodeInterface8;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.codehaus.groovy.runtime.callsite.CallSiteArray;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;

public class MyClass
implements GroovyObject {
    private static /* synthetic */ ClassInfo $staticClassInfo;
    public static transient /* synthetic */ boolean __$stMC;
    private transient /* synthetic */ MetaClass metaClass;
    private static /* synthetic */ SoftReference $callSiteArray;

    @Generated
    public MyClass() {
        MetaClass metaClass;
        CallSite[] callSiteArray = MyClass.$getCallSiteArray();
        this.metaClass = metaClass = this.$getStaticMetaClass();
    }

    public int add() {
        CallSite[] callSiteArray = MyClass.$getCallSiteArray();
        int a = 1;
        int b = 2;
        if (!BytecodeInterface8.isOrigInt() || __$stMC || BytecodeInterface8.disabledStandardMetaClass()) {
            return DefaultTypeTransformation.intUnbox((Object)callSiteArray[0].call((Object)a, (Object)b));
        }
        return a + b;
    }

    public static void main(String ... args) {
        CallSite[] callSiteArray = MyClass.$getCallSiteArray();
        MyClass m = (MyClass)ScriptBytecodeAdapter.castToType((Object)callSiteArray[1].callConstructor(MyClass.class), MyClass.class);
        callSiteArray[2].call(callSiteArray[3].callGetProperty(System.class), callSiteArray[4].call((Object)m));
    }

    protected /* synthetic */ MetaClass $getStaticMetaClass() {
        if (this.getClass() != MyClass.class) {
            return ScriptBytecodeAdapter.initMetaClass((Object)this);
        }
        ClassInfo classInfo = $staticClassInfo;
        if (classInfo == null) {
            $staticClassInfo = classInfo = ClassInfo.getClassInfo(this.getClass());
        }
        return classInfo.getMetaClass();
    }

    @Generated
    @Internal
    @Transient
    public MetaClass getMetaClass() {
        MetaClass metaClass = this.metaClass;
        if (metaClass != null) {
            return metaClass;
        }
        this.metaClass = this.$getStaticMetaClass();
        return this.metaClass;
    }

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

    private static /* synthetic */ void $createCallSiteArray_1(String[] stringArray) {
        stringArray[0] = "plus";
        stringArray[1] = "<$constructor$>";
        stringArray[2] = "println";
        stringArray[3] = "out";
        stringArray[4] = "add";
    }

    private static /* synthetic */ CallSiteArray $createCallSiteArray() {
        String[] stringArray = new String[5];
        MyClass.$createCallSiteArray_1(stringArray);
        return new CallSiteArray(MyClass.class, stringArray);
    }

    private static /* synthetic */ CallSite[] $getCallSiteArray() {
        CallSiteArray callSiteArray;
        if ($callSiteArray == null || (callSiteArray = (CallSiteArray)$callSiteArray.get()) == null) {
            callSiteArray = MyClass.$createCallSiteArray();
            $callSiteArray = new SoftReference<CallSiteArray>(callSiteArray);
        }
        return callSiteArray.array;
    }
}

GroovyObject源码

package groovy.lang;

import groovy.transform.Internal;

/**
 * The interface implemented by all Groovy objects.
 * <p>
 * Especially handy for using Groovy objects when in the Java world.
 */
public interface GroovyObject {

    /**
     * Invokes the given method.
     *
     * @param name the name of the method to call
     * @param args the arguments to use for the method call
     * @return the result of invoking the method
     */
    @Internal // marked as internal just for backward compatibility, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
    default Object invokeMethod(String name, Object args) {
        return getMetaClass().invokeMethod(this, name, args);
    }

    /**
     * Retrieves a property value.
     *
     * @param propertyName the name of the property of interest
     * @return the given property
     */
    @Internal // marked as internal just for backward compatibility, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
    default Object getProperty(String propertyName) {
        return getMetaClass().getProperty(this, propertyName);
    }

    /**
     * Sets the given property to the new value.
     *
     * @param propertyName the name of the property of interest
     * @param newValue     the new value for the property
     */
    @Internal // marked as internal just for backward compatibility, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
    default void setProperty(String propertyName, Object newValue) {
        getMetaClass().setProperty(this, propertyName, newValue);
    }

    /**
     * Returns the metaclass for a given class.
     *
     * @return the metaClass of this instance
     */
    MetaClass getMetaClass();

    /**
     * Allows the MetaClass to be replaced with a derived implementation.
     *
     * @param metaClass the new metaclass
     */
    void setMetaClass(MetaClass metaClass);
}

  1. 分析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值