Байт-код Java - это набор инструкций для виртуальной машины Java ( JVM).
A Программисту Java совсем не обязательно знать или понимать байт-код Java. Однако, как предлагается в журнале IBM developerWorks, «Понимание байт-кода и того, какой байт-код может быть сгенерирован компилятором Java, помогает программисту Java так же, как знание сборка помогает программисту C или C++. "
JVM является одновременно стековой машиной и регистрационный аппарат. Каждый фрейм для вызова метода имеет «стек операндов» и массив «локальных переменных». Стек операндов используется для операндов для вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры , а также используются для передачи аргументов метода. Максимальный размер стека операндов и массива локальных переменных, вычисляемый компилятором, является частью атрибутов каждого метода. Каждый может иметь независимый размер от 0 до 65 535 значений, где каждое значение составляет 32 бита. Типы long
и double
, которые являются 64-битными, занимают две последовательные локальные переменные (которые не должны быть выровнены по 64-битному в массиве локальных переменных) или одно значение в стеке операндов (но считаются как две единицы в глубине стека).
Каждый байт-код состоит из одного байта, который представляет код операции , а также ноль или более байтов для операндов.
Из 256 возможных байтовых кодов операций, по состоянию на 2015 год, 202 используются (~ 79%), 51 зарезервирован для будущего использования (~ 20%), а 3 инструкции (~ 1%) постоянно зарезервированы для использования реализациями JVM. Два из них (impdep1
и impdep2
) предназначены для обеспечения ловушек для программного и аппаратного обеспечения, зависящего от реализации, соответственно. Третий используется отладчиками для реализации точек останова.
Инструкции делятся на несколько широких групп:
aload_0
, istore
)ladd
, fcmpl
)i2b
, d2i
)new
, putfield
)swap
, dup2
)ifeq
, goto
)invokespecial
, areturn
)Есть также несколько инструкций для ряда более специализированных задач, таких как генерация исключений, синхронизация и т. Д.
Многие инструкции имеют префиксы и / или суффиксы, относящиеся к типам операндов, которые они работают над. Это следующие:
Префикс/суффикс | Тип операнда |
---|---|
i | целое число |
l | длинный |
s | короткий |
b | байт |
c | символ |
f | плавающий |
d | двойной |
a | ссылка |
Например, iadd
добавит два целых числа, а dadd
добавит два двойных числа. const
, load
и Инструкции store
также могут иметь суффикс вида _n
, где n - это число от 0 до 3 для load
и store
. Максимальное значение n для const
зависит от типа.
Инструкции const
помещают значение указанного типа в стек. Например, iconst_5
поместит в стек целое число (32-битное значение) со значением 5, тогда как dconst_1
поместит двойное (64-битное значение с плавающей запятой) со значением 1 в стек. Также существует aconst_null
, который подталкивает ссылку null
. Число n для инструкций load
и store
указывает индекс в массиве локальных переменных для загрузки или сохранения. Инструкция aload_0
помещает объект в локальной переменной 0 в стек (обычно это этот
объект). istore_1
сохраняет целое число наверху стека в локальную переменную 1. Для локальных переменных, превышающих 3, суффикс отбрасывается, и необходимо использовать операнды.
Рассмотрим следующий код 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); }
Компилятор Java может преобразовать приведенный выше код Java в байтовый код следующим образом: предполагая, что указанное выше было помещено в метод:
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; // Поле java / lang / System.out: Ljava / io / PrintStream; 34: iload_1 35: invokevirtual # 85; // Метод java / io / PrintStream.println: (I) V 38: iinc 1, 1 41: goto 2 44: return
Наиболее распространенный языковой таргетинг Виртуальная машина Java путем создания байт-кода Java - это Java. Первоначально существовал только один компилятор, компилятор javac из Sun Microsystems, который компилирует исходный код Java в Байт-код Java; но поскольку теперь доступны все спецификации для байт-кода Java, другие стороны предоставили com Пилеры, которые производят байт-код Java. Примеры других компиляторов включают:
Некоторые проекты предоставляют ассемблеры Java, позволяющие писать байт-код Java вручную. Код ассемблера также может быть сгенерирован машиной, например компилятором, предназначенным для виртуальной машины Java. Известные ассемблеры Java включают:
Другие разработали компиляторы для разных языков программирования для работы с виртуальной машиной Java, такие как:
Сегодня доступно несколько машин, как бесплатных, так и коммерческих.
Если выполнение байт-кода Java на виртуальной машине Java нежелательно, разработчик также может скомпилировать исходный код Java или байт-код непосредственно в машинный код с помощью таких инструментов, как компилятор GNU для Java (GCJ). Некоторые процессоры могут выполнять байт-код Java изначально. Такие процессоры называются процессорами Java.
Виртуальная машина Java обеспечивает некоторую поддержку языков с динамическими типами. Большая часть существующего набора инструкций JVM является статически типизированной - в том смысле, что для вызовов методов проверяется тип сигнатуры во время компиляции, без механизма, чтобы отложить это решение до время выполнения, или выбрать отправку метода с помощью альтернативного подхода.
JSR 292 (Поддержка динамически типизированных языков на платформе Java) добавил новую инструкцию invokedynamic
на уровне JVM, чтобы разрешить вызов метода, основанного на динамической проверке типа (вместо существующей инструкции invokevirtual
с статической проверкой типа). Da Vinci Machine - это прототип виртуальной машины, на которой размещены расширения JVM, предназначенные для поддержки динамических языков. Все JVM, поддерживающие JSE 7, также включают код операции invokedynamic
.
Wikibook Программирование на Java имеет страницу по теме: Байт-код Java |