【问题标题】:How does Java primitive wrapper classes support additional methods in Groovy?Java 原始包装类如何支持 Groovy 中的其他方法?
【发布时间】:2020-04-20 01:42:11
【问题描述】:

我来自 Java 背景,现在我正在学习 Groovy。以下代码是有效的 Groovy 代码。

def val=1
println val.getClass() //will print java.lang.Integer
def ans=3.intdiv(2)    //performs integer division

我想知道,Groovy 如何将intdiv 这样的方法添加到最终的java.lang.Integer 类中?还有很多其他这样的方法,比如timesuptodowntostep等等。这些方法被添加到最终的 Java 类中。怎么可能?

【问题讨论】:

    标签: java groovy


    【解决方案1】:

    您提到的那些方法称为默认 Groovy 方法,其中大部分在 org.codehaus.groovy.runtime.DefaultGroovyMethods 类中实现。像intdiv 这样的方法不会添加到最终的Integer 类中,而是在默认Groovy 方法中为任何Number 类实现。现在,当 Groovy 编译器将 Groovy 代码编译为字节码时,它会检测到类似 2.intdiv(3) 的内容,并将此表达式替换为类似 DefaultGroovyMethods.intdiv(2,3) 的内容。

    为了使这个插图更加清晰,请查看以下 Groovy 类:

    import groovy.transform.CompileStatic
    
    @CompileStatic
    class SomeClass {
    
        static void main(String[] args) {
            def val=1
            println val.getClass()
            def ans = 3.intdiv(2)
            println ans
        }
    }
    

    当您将其编译为SomeClass.class 文件,然后将其反编译为 Java(例如,通过在 IntelliJ IDEA 中打开此类文件),您将看到以下 Java 类等价物:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    import groovy.lang.GroovyObject;
    import groovy.lang.MetaClass;
    import groovy.transform.Generated;
    import groovy.transform.Internal;
    import org.codehaus.groovy.runtime.DefaultGroovyMethods;
    import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
    
    public class SomeClass implements GroovyObject {
        @Generated
        public SomeClass() {
            MetaClass var1 = this.$getStaticMetaClass();
            this.metaClass = var1;
        }
    
        public static void main(String... args) {
            int val = 2;
            int some = DefaultTypeTransformation.intUnbox(DefaultGroovyMethods.intdiv(Integer.valueOf(val), 3));
            DefaultGroovyMethods.println(SomeClass.class, some);
            Object var10000 = null;
        }
    
        @Generated
        @Internal
        public MetaClass getMetaClass() {
            MetaClass var10000 = this.metaClass;
            if (var10000 != null) {
                return var10000;
            } else {
                this.metaClass = this.$getStaticMetaClass();
                return this.metaClass;
            }
        }
    
        @Generated
        @Internal
        public void setMetaClass(MetaClass var1) {
            this.metaClass = var1;
        }
    }
    

    你可以看到

    def ans = 3.intdiv(2)
    

    变成

    int some = DefaultTypeTransformation.intUnbox(DefaultGroovyMethods.intdiv(Integer.valueOf(val), 3));
    

    没有魔法,只有 Groovy 编译器知道如何对抽象语法树进行此类转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多