Байт-код Java - Java bytecode
Байт-код Java это Набор инструкций из Виртуальная машина Java (JVM).
Отношение к Java
А Ява программисту вообще не нужно знать или понимать байт-код Java. Однако, как предлагается в IBM журнал developerWorks, "Понимание байт-кода и того, какой байт-код может быть сгенерирован Компилятор Java помогает программисту на Java так же, как и знание сборка помогает C или же C ++ программист."[1]
Архитектура набора команд
JVM - это одновременно штабелеукладчик и зарегистрировать машину. Каждый Рамка для вызова метода есть «стек операндов» и массив «локальных переменных».[2]:2.6 Стек операндов используется для операндов для вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры а также используются для передачи аргументов метода. Максимальный размер стека операндов и массива локальных переменных, вычисляемый компилятором, является частью атрибутов каждого метода.[2]:4.7.3 Каждый может иметь независимый размер от 0 до 65 535 значений, где каждое значение составляет 32 бита. длинный и двойной типы, которые являются 64-битными, занимают две последовательные локальные переменные[2]:2.6.1 (которые не должны быть выровнены по 64 бита в массиве локальных переменных) или одно значение в стеке операндов (но учитываются как две единицы в глубине стека).[2]:2.6.2
Набор инструкций
Каждый байт-код состоит из одного байта, который представляет код операции, а также ноль или более байтов для операндов.[2]:2.11
Из 256 возможных байтов коды операций, по состоянию на 2015 год[Обновить], 202 используются (~ 79%), 51 зарезервированы для использования в будущем (~ 20%), а 3 инструкции (~ 1%) постоянно зарезервированы для использования реализациями JVM.[2]:6.2 Два из них (impdep1 и impdep2) должны обеспечивать ловушки для программного и аппаратного обеспечения, зависящего от реализации, соответственно. Третий используется отладчиками для реализации точек останова.
Инструкции делятся на несколько больших групп:
- Загрузить и сохранить (например, 
aload_0,istore) - Арифметика и логика (например, 
лестница,fcmpl) - Преобразование типа (например, 
i2b,d2i) - Создание и управление объектами (
новый,путфилд) - Управление стеком операндов (например, 
замена,dup2) - Передача управления (например, 
ifeq,идти к) - Вызов и возврат метода (например, 
вызывает особый,возвращение) 
Также есть несколько инструкций для ряда более специализированных задач, таких как генерация исключений, синхронизация и т. Д.
Многие инструкции имеют префиксы и / или суффиксы, относящиеся к типам операндов, с которыми они работают.[2]:2.11.1 Это следующие:
| Префикс Суффикс | Тип операнда | 
|---|---|
я | целое число | 
л | длинный | 
s | короткая | 
б | байт | 
c | персонаж | 
ж | плавать | 
d | двойной | 
а | ссылка | 
Например, я добавить добавит два целых числа, а папа добавит два дубля. В const, нагрузка, и хранить инструкции также могут иметь суффикс в форме _п, куда п это число от 0 до 3 для нагрузка и хранить. Максимум п за const отличается по типу.
В const инструкции помещают значение указанного типа в стек. Например, iconst_5 поместит в стек целое число (32-битное значение) со значением 5, а dconst_1 поместит в стек двойное (64-битное значение с плавающей запятой) со значением 1. Также есть aconst_null, что подталкивает ноль ссылка. В п для нагрузка и хранить Инструкции задают индекс в массиве локальных переменных для загрузки или сохранения. В aload_0 инструкция помещает объект в локальной переменной 0 в стек (обычно это это объект). istore_1 сохраняет целое число наверху стека в локальную переменную 1. Для локальных переменных, превышающих 3, суффикс отбрасывается, и необходимо использовать операнды.
Пример
Рассмотрим следующий код Java:
внешний:за (int я = 2; я < 1000; я++) {    за (int j = 2; j < я; j++) {        если (я % j == 0)            Продолжить внешний;    }    Система.из.println (я);}Компилятор Java может преобразовать приведенный выше код Java в байт-код следующим образом, предполагая, что это было помещено в метод:
0:   iconst_21:   istore_12:   iload_13:   сипуш  10006:   if_icmpge       449:   iconst_210:  istore_211:  iload_212:  iload_113:  if_icmpge       3116:  iload_117:  iload_218:  ирем19:  ifne    2522:  идти к    3825:  iinc    2, 128:  идти к    1131:  getstatic       #84; // Поле java / lang / System.out:Ljava / io / PrintStream;34:  iload_135:  invokevirtual   #85; // Метод java / io / PrintStream.println: (I) V38:  iinc    1, 141:  идти к    244:  возвращатьсяПоколение
Самый распространенный языковой таргетинг Виртуальная машина Java путем создания байт-кода Java - это Java. Первоначально существовал только один компилятор, javac компилятор из Sun Microsystems, который компилирует Исходный код Java в байт-код Java; но поскольку теперь доступны все спецификации для байт-кода Java, другие стороны предоставили компиляторы, которые производят байт-код Java. Примеры других компиляторов:
- Компилятор Eclipse для Java (ECJ)
 - Jikes, компилируется из Java в байт-код Java (разработанный IBM, реализованный в C ++ )
 - Espresso, компилируется из Java в байт-код Java (только для Java 1.0)
 - Компилятор GNU для Java (GCJ), компилируется из Java в байт-код Java; он также может компилироваться в родной Машинный код и был частью Коллекция компиляторов GNU (GCC) до версии 6.
 
Некоторые проекты предоставляют ассемблеры Java, позволяющие писать байт-код Java вручную. Код сборки также может быть сгенерирован машиной, например компилятором, нацеленным на Виртуальная машина Java. Известные ассемблеры Java включают:
- Жасмин, берет текстовые описания для классов Java, написанные в простом синтаксисе, подобном ассемблере, с использованием набора команд виртуальной машины Java, и генерирует файл класса Java[3]
 - Ямайка, а макрос язык ассемблера для Виртуальная машина Java. Синтаксис Java используется для определения класса или интерфейса. Тела методов указываются с помощью инструкций байт-кода.[4]
 - Krakatau Bytecode Tools, в настоящее время содержит три инструмента: декомпилятор и дизассемблер для файлов классов Java и ассемблер для создания файлов классов.[5]
 - Lilac, ассемблер и дизассемблер для Виртуальная машина Java.[6]
 
Другие разработали компиляторы для разных языков программирования для виртуальной машины Java, например:
- Холодный синтез
 - JRuby и Jython, два языки сценариев на основе Рубин и Python
 - Apache Groovy, необязательно типизированный и динамический язык общего назначения с возможностями статической типизации и статической компиляции
 - Scala, типобезопасный язык программирования общего назначения, поддерживающий объектно-ориентированное и функциональное программирование.
 - JGNAT и AppletMagic, скомпилировать из языка Ада в байт-код Java
 - Компиляторы байтового кода C в Java[мертвая ссылка ]
 - Clojure, функциональный неизменяемый язык программирования общего назначения на Лисп семья с упором на параллелизм
 - Кава, реализация Схема язык программирования, также диалект Лисп.
 - MIDletPascal
 - Сценарий JavaFX код компилируется в байт-код Java
 - Котлин, статически типизированный язык программирования общего назначения с выводом типа
 - Object Pascal исходный код компилируется в байт-код Java с использованием Free Pascal 3.0+ компилятор.[7][8]
 
Исполнение
Сегодня доступно несколько машин, как бесплатных, так и коммерческих.
Если выполнение байт-кода Java на виртуальной машине Java нежелательно, разработчик также может скомпилировать исходный код Java или байт-код непосредственно в собственный машинный код с помощью таких инструментов, как Компилятор GNU для Java (GCJ). Некоторые процессоры могут выполнять байт-код Java изначально. Такие процессоры называют Процессоры Java.
Поддержка динамических языков
В Виртуальная машина Java оказывает некоторую поддержку динамически типизированные языки. Большая часть существующего набора инструкций JVM статически типизированный - в том смысле, что сигнатуры вызовов методов проверяются на время компиляции, без механизма, чтобы отложить это решение до время выполнения, либо выбрать способ отправки альтернативным подходом.[9]
JSR 292 (Поддержка динамически типизированных языков на платформе Java)[10] добавил новый invokedynamic инструкция на уровне JVM, чтобы разрешить вызов метода, основанного на динамическом проверка типа (вместо существующего статически проверенного типа invokevirtual инструкция). В Машина да Винчи - это прототип реализации виртуальной машины, в которой размещены расширения JVM, предназначенные для поддержки динамических языков. Все JVM с поддержкой JSE 7 также включают invokedynamic код операции.
Смотрите также
- Списки команд байт-кода Java
 - Файл класса Java
 - Список языков JVM
 - Инструменты резервного копирования Java
 - Компиляторы виртуальных машин C в Java
 - JStik
 - Общий промежуточный язык (CIL), соперник байт-кода Java от Microsoft
 - ObjectWeb ASM
 - Инженерная библиотека байтового кода
 
Рекомендации
- ^ Понимание байт-кода делает вас лучшим программистом
 - ^ а б c d е ж грамм Линдхольм, Тим; Йеллин, Франк; Браха, Гилад; Бакли, Алекс (13 февраля 2015). Спецификация виртуальной машины Java (Java SE 8-е изд.).
 - ^ Домашняя страница Jasmin
 - ^ Ямайка: ассемблер макросов виртуальной машины Java (JVM)
 - ^ Домашняя страница Кракатау
 - ^ Домашняя страница сирени
 - ^ Примечания к выпуску Free Pascal 3.0
 - ^ Free Pascal JVM Target
 - ^ Наттер, Чарльз (2007-01-03). "InvokeDynamic: Действительно полезно?". Получено 2008-01-25.
 - ^ см. JSR 292
 
внешняя ссылка
- Спецификация виртуальной машины Oracle Java
 - Языки программирования для виртуальной машины Java
 - Визуализатор байт-кода - средство просмотра и отладчик байт-кода (бесплатный плагин Eclipse)
 - AdaptJ StackTrace - отладка на уровне байт-кода с полным контролем над стеком, локальными переменными и потоком выполнения
 - Java Class Unpacker - плагин для Total Commander, он позволяет открывать файлы классов в виде сжатых архивов и видеть поля и методы как файлы. Байт-код можно просмотреть как текст с помощью F3.