Те методы, которые вы упомянули, называются По умолчанию Groovy Методы , и большинство из них реализованы в классе org.codehaus.groovy.runtime.DefaultGroovyMethods
. Такой метод, как intdiv
, не добавляется в окончательный класс Integer
, но вместо этого он реализуется для любого класса Number
в стандартных Groovy методах. Теперь, когда 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));
Волхвов нет c это просто Groovy компилятор, который знает, как выполнять такие преобразования в дереве абстрактного синтаксиса.