您提到的那些方法称为默认 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 编译器知道如何对抽象语法树进行此类转换。