Байт-код Java — набор инструкций, исполняемых виртуальной машиной Java. Каждый код операции байт-кода — один байт; используются не все 256 возможных значений кодов операций, 51 из них зарезервирован для использования в будущем.

Для программирования на языке Java или других JVM-совместимых языках знание особенностей байт-кода не обязательно, тем не менее, «понимание байт-кода и понимание механизмов его генерации компилятором Java помогает Java-программисту так же, как и знание языка ассемблера помогает программисту, пишущему на Си или C++»Peter Haggar, Understanding bytecode makes you a better programmer // IBM DeveloperWorks, 01 Jul 2001.

Инструкции Код CA16 зарезервирован для использования отладчиком и не используется языком, как и коды FE16 и FF16, которые зарезервированы для использования виртуальной машиной и отладчиками. Коды в диапазоне CB16—FD16 в текущей версии JVM не используются и зарезервированы для будущих дополнений.

Инструкции можно разделить на несколько групп: загрузка и сохранение (например, ALOAD_0, ISTORE), арифметические и логические операции (например, IADD, FCMPL), преобразование типов (например, I2B, D2I), создание и преобразование объекта (например, NEW, PUTFIELD), управление стеком (например, DUP, POP), операторы перехода (например, GOTO, IFEQ), вызовы методов и возврат (например, INVOKESTATIC, IRETURN).

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

Многие инструкции имеют префиксы или суффиксы, соответствующие их операндам:

Префикс или суффикс Тип операнда I integer L long S short B byte C character F float D double A reference

Например, операция IADD — сложение двух целых чисел, в то время как FADD — сложение чисел с плавающей точкой.

Пример Код на языке Java: outer: for (int i = 2; i < 1000; i++) { for (int j = 2; j < i; j++) { if (i % j == 0) continue outer;

System.out.println (i);

компилятор может транслировать в следующий байт-код: 0: iconst_2 1: istore_1 2: iload_1 3: sipush 1000 6: if_icmpge 44 9: iconst_2 10: istore_2 11: iload_2 12: iload_1 13: if_icmpge 31 16: iload_1 17: iload_2 18: irem 19: ifne 25 22: goto 38 25: iinc 2, 1 28: goto 11 31: getstatic #84; //Field java/lang/System.out:Ljava/io/PrintStream; 34: iload_1 35: invokevirtual #85; //Method java/io/PrintStream.println:(I)V 38: iinc 1, 1 41: goto 2 44: return

Генерация

В большинстве случаев байт-код Java генерируется для исполнения на виртуальной машине Java из исходного кода на языке Java. Единственный оригинальный компилятор, преобразующий код на языке Java в байт-код Java — это Javac, созданный компанией Sun Microsystems. Но поскольку все спецификации байт-кода Java доступны, существуют и сторонние компиляторы, генерирующие этот байт-код. Примеры таких компиляторов:  — компилирует код на Java в Java-байт-код (разработан IBM, написан на C++), Espresso — компилирует код на Java в Java-байт-код (для версии Java 1.0), GCJ (GNU Compiler for Java) — компилирует код на Java в Java-байт-код, также способен компилировать в нативный машинный код, является частью GNU Compiler Collection. Для некоторых проектов существуют компиляторы, позволяющие генерировать байт-код для JVM из исходного кода на другом языке программирования, среди таких проектов:

ColdFusion, JRuby и Jython (для Ruby и Python соответственно), Groovy (скриптовый язык, основанный на Java), Scala, Kotlin, JGNAT и AppletMagic, компиляторы с языка Си в Java-байт-код, Clojure, MIDletPascal, JavaFX Script.

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

См. также smali

Примечания

Ссылки Chapter 6. The Java Virtual Machine Instruction Set

*