Статическая инициализация в ActionScript при обращении к константе

Как вы считаете, когда вызывается статическая инициализация класса в as3? Правильно, при первом обращении к классу, его свойствам, методам и т.д. А что на счет констант? Рассмотрим пример.

Пусть у нас есть класс D , содержащий статическую константу PI  и статический конструктор, выводящий в консоль текст «Static int»:

Для теста просто распечатываем значение константы в консоль:

После запуска я вижу:

А мой коллега:

В чем же дело? А дело в том, что мы используем разные компиляторы. Получается, что компилятор AIR SDK при обращении к константам класса не вызывает статический инициализатор (при обращении к свойствам или методам — вызывает), но если скомпилировать флешку с помощью Flex SDK, то статический инициализатор вызывается.

Почему так происходит можно наглядно продемонстрировать посмотрев набор инструкций конструктора декомпилированной флешки.

При компиляции новой версией компилятора, которая используется в AIR SDK мы получаем

А вот SWF, скомпилированный с помощью Flex SDK

И так, в первом случае вызов константы заменяется на использование её значения, без обращения к классу.

Оказывается надо внимательно читать документацию:

ASC 2.0
Улучшение расчета констант
Теперь большинство констант рассчитываются на этапе компиляции. Это может изменить порядок инициализации классов. Так как ссылки на статические константы могут быть заменены рассчитанными значениями констант, MyClass.SOME_CONSTANT может не вызвать статическую инициализацию класса MyClass.

https://helpx.adobe.com/flash-builder/actionscript-compiler-backward-compatibility.html

Именно это мы и видим в декомпилированном flash файле.

В итоге. Радует, что новый компилятор исключает множество лишних инструкций и тем самым должен ускорить выполнение кода. Но реализованная в данном случае оптимизация вызывает вопросы: я считаю, что обращение к константе класса должно инициализировать класс, на этом может быть завязана определенная логика. Ну и еще раз убеждаемся, что программировать на ActionScript 3 надо с осторожностью.

Добавить комментарий