Что такое байт-код JVM? Объяснение файлов классов Java

Байткод JVM — это компактный набор инструкций, который выполняет виртуальная машина Java. Узнайте, как работают файлы .class, почему моды переписывают байткод и какое место ASM занимает в этом процессе.

Conceptsby trqUpdated June 4, 2026
Key takeaways
  • Байт-код JVM — это компактный набор инструкций, который выполняет виртуальная машина Java.
  • Компилятор Java генерирует байт-код в файлах .class, а не в машинном коде.
  • Один и тот же файл .class может работать на любой платформе с установленной Java runtime, и это суть формата.
  • Моды переписывают байт-код, чтобы изменить скомпилированную игру, не имея при этом доступа к исходному коду.

Байткод JVM — это набор инструкций, который выполняет виртуальная машина Java. При компиляции исходного кода Java компилятор не генерирует машинный код для вашего процессора. Он генерирует байткод — компактный, переносимый формат, хранящийся в файлах .class. JVM считывает эти инструкции во время выполнения и преобразует их в машинный код по мере необходимости.

Где используется Opal

Opal — это мод для Fabric, и инструменты для моддинга, на которых он основан, выполняют работу с байт-кодом за вас, поэтому вам не нужно вручную работать с опкодами. Если вы хотите добавить поведение на обычном JavaScript, обратитесь к введению в скриптинг.

Как исходный код превращается в байткод

Файл .java — это текст, написанный человеком. Файл .class — это скомпилированный вывод, который запускается JVM. Компилятор читает ваш исходный код, проверяет его и записывает один файл .class на каждый класс, содержащий инструкции байткода, а также таблицу констант, таблицы методов и другие метаданные.

Байткод не привязан к какому-либо конкретному процессору. Один и тот же файл .class может работать в Windows, macOS, Linux или на любой системе с Java runtime, поскольку JVM — это слой, который знает, как выполнять инструкции на локальной машине. Именно эта переносимость является сутью формата.

Как выглядят инструкции

Байткод — это набор инструкций, основанный на стеке. Большинство операций помещают значения в операндную стек, извлекают их оттуда и помещают результат. Нет выделения регистров, о котором нужно рассуждать; модель намеренно проста, чтобы JVM могла быстро проверять и выполнять ее.

Несколько примеров опкодов дают представление:

ОпкодЧто он делает
iloadПомещает локальную переменную типа int в стек
iaddИзвлекает два целых числа из стека, помещает их сумму
invokevirtualВызывает метод экземпляра
getfieldЧитает поле экземпляра
returnВозвращается из метода

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

Почему байткод важен для модов

Байткод важен, потому что он позволяет изменять поведение без исходного кода. Мод для Minecraft почти никогда не имеет исходный код игры. Вместо этого у него есть скомпилированная игра на диске. Чтобы добавить или изменить функцию, мод считывает существующий байткод, переписывает его и передает результат обратно JVM во время загрузки классов.

Именно так работают фреймворки патчинга, внедряя хуки в методы, которые им не принадлежат. Они находят нужное место в скомпилированном методе и вставляют вызов кода мода. Работа на уровне байткода позволяет моду подключаться к игре, даже не видя ни одной строки оригинального Java-кода.

Где здесь ASM

ASM — это Java-библиотека для чтения, записи и преобразования байткода. Она разбирает файл .class на события или дерево, позволяет изменять инструкции и генерирует обратно валидный файл .class. Она небольшая, быстрая и работает близко к исходному формату, поэтому более высокоуровневые инструменты моддинга строятся на её основе, а не разбирают файлы классов самостоятельно.

Большинство моддеров никогда напрямую не вызывают ASM. Они используют более высокоуровневый слой, который скрывает опкоды и предоставляет более удобный способ сказать: «запусти мой код в начале этого метода». В глубине души этот слой редактирует байткод, часто через ASM.

Часто задаваемые вопросы