In - статически скомпилированный - Java, статический код, который вызывает код экземпляра, не будет компилироваться. Это связано с высоким риском того, что статический код не вызывается для экземпляра, а вызывается непосредственно для типа, что может привести к ошибкам во время выполнения.
Хотя теоретически можно статически скомпилировать код Groovy, по умолчанию он компилируется динамически. «Динамически» означает, что отчасти отсутствуют прямые ссылки между артефактами кода (такими как методы, переменные, конструкторы, классы и т. Д.) В байт-коде.
Рассмотрим следующий класс Groovy:
class StaticClass {
static def someString = "someString"
static def staticMethod() {
this.someString
}
static def main(args) {
StaticClass.staticMethod()
new StaticClass().staticMethod()
}
}
Используя Groovy-компилятор, groovyc
, он компилируется в код, который обеспечивает динамическое выполнение во время выполнения. Следующий код представляет вышеуказанный метод main(..)
после компиляции:
public static void main(String[] args) {
CallSite[] arrayOfCallSite = $getCallSiteArray();
arrayOfCallSite[0].call($get$$class$StaticClass());
arrayOfCallSite[1].call(arrayOfCallSite[2].callConstructor(
$get$$class$StaticClass())); return;
}
Что на самом деле происходит, когда вызывается этот код, трудно сказать, поскольку во время выполнения задействован очень сложный и вложенный поток решений и рабочий процесс, который зависит от нескольких факторов.
Поскольку в этом простом примере особых случаев нет (метакласс, класс расширения, замыкания, перехватчики и т. Д.), Вполне вероятно, что, в конце концов, вызывается реализация GroovyObject.invokeMethod(String, Object)
.
Во всей документации Groovy (включая руководство пользователя и вики, но до отсутствуют JavaDocs и отсутствующие исходные файлы в исходном дистрибутиве) механизмы этого "динамического метапрограммирования во время выполнения" скрыты от пользователь - вероятно, из-за его огромной сложности и из-за того, что пользователю не нужно знать об этом подробно. Это довольно интересно для разработчиков ядра Groovy.
В конце концов, трудно сказать , почему this
работает, когда не вызывается для экземпляра объекта. Другой вопрос был: должно работать ...