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++ в тексте статьи :((. Или у вас ИИ тэги статьи выставляет?
Хотя бы потому, что в 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). Работает с полями строкового и примитивных типов.4.7.2. The ConstantValue Attribute
TheConstantValue
attribute is a fixed-length attribute in theattributes
table of afield_info
structure (§4.5). AConstantValue
attribute represents the value of a constant expression (JLS §15.28), and is used as follows:
- If the
ACC_STATIC
flag in theaccess_flags
item of thefield_info
structure is set, then the field represented by thefield_info
structure is assigned the value represented by itsConstantValue
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()
.
Манипуляции с байт-кодом Java