Pull to refresh

Comments 6

В байткоде для начальных значений полей места просто не предусмотрено, они просто инициализируются в значение по умолчанию. Чтобы добавить аналог int x = 10; надо 1) добавить само поле 2) во все конструкторы добавить iload/putfield 3) если конструкторов нет вообще — добавить конструктор.

Примечание: я установил начальное значение в 4. Но в консоль всё равно выводится 0. То есть, добавленный атрибут не инициализируется в 4. Почему – я не знаю.

Ответ есть в документации.

This parameter is only used for static fields. Its value is ignored for non static fields, which must be initialized through bytecode instructions in constructors or methods.

Такая модель памяти используется не только в Java, она также существует и в C++. В большей или меньшей степени то же касается и других языков.

Пардонте, но это единственное упоминание C++ в тексте статьи :((. Или у вас ИИ тэги статьи выставляет?

Если Java, то JavaScript, очевидно же.

Начинать статью с «компилятор Java обработает наш код» и потом хреначить весь код на Kotlin это какая-то шиза.

Хотя бы потому, что в class-файлах, генерируемых компилятором Котлина, целая гора требухи, которой нет в class-файлах, генерируемых компилятором Java. Те же проверки на null для значений non-nullable типов или Kotlin-специфичные аннотации, например.

Чтение и синтаксический разбор этого файла выполняет ClassLoader.

ClassLoader откуда-то берёт байтики class-файла и просит JVM загрузить из них класс, всё. Никакого «синтаксического разбора» он не делает.

На этой странице docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.1 перечислены все типы констант.

Ссылаться на спецификацию Java 7 в 2021 году, когда вышел оригинал этой статьи, несколько странно. На тот момент прошло уже более 7 лет с выхода Java 8, а актуальной на тот момент LTS-версией была 11 на начало года и 17 — в конце. Типов констант со времён Java 7 поприбавилось.

Если из этого перевода вы так и не поняли, что это за пул констант такой и с чем его едят, то рекомендую хабрастатью про это: https://habr.com/ru/articles/222519/
C момента написания появилось некоторое количество новых типов записей в constant pool, но основы неизменны и переданы отлично.

Такая модель памяти используется не только в Java, она также существует и в C++.

И в Java, и в C++ «моделью памяти» называют несколько иное. А именно, гарантии видимости изменений в ОЗУ при работе многопоточной программы.

Примечание: я установил начальное значение в 4. Но в консоль всё равно выводится 0. То есть, добавленный атрибут не инициализируется в 4. Почему – я не знаю.

Как уже указали в комментариях, для нестатических полей класса нужно явно инициализировать их в конструкторе. Здесь проектировщики API библиотеки ASM переусердствовали в погоне за удобством.

ifilonov

В байткоде для начальных значений полей места просто не предусмотрено, они просто инициализируются в значение по умолчанию.

Не совсем так. Для статических полей предусмотрен аттрибут ConstantValue (JVMS §4.7.2). Работает с полями строкового и примитивных типов.

JVMS §4.7.2
4.7.2. The ConstantValue Attribute

The ConstantValue attribute is a fixed-length attribute in the attributes table of a field_info structure (§4.5). A ConstantValue attribute represents the value of a constant expression (JLS §15.28), and is used as follows:
  • If the ACC_STATIC flag in the access_flags item of the field_info structure is set, then the field represented by the field_info structure is assigned the value represented by its ConstantValue attribute as part of the initialization of the class or interface declaring the field (§5.5). This occurs prior to the invocation of the class or interface initialization method of that class or interface (§2.9.2).
  • Otherwise, the Java Virtual Machine must silently ignore the attribute.


Но с не static final полями он не работает и именно об это споткнулся автор, невнимательно читавший JavaDoc. Тут, конечно, и авторы ASM хороши, накостылявшие в API такую сигнатуру для visitField().
Sign up to leave a comment.