Что такое byte code java
Перейти к содержимому

Что такое byte code java

  • автор:

Байт-код Java: определение, инструкции, методы написания и примеры

Lorem ipsum dolor

Байт-код Java — это совокупность команд, которые исполняются в виртуальной машине Java. Одна команда равняется одному байту, поэтому байт-код Java кажется довольно примитивным , в едь одна команда будет равняться одной букве.

Даже начинающий Java-разработчик знает, что программный код, разработанный на этом языке, может запускаться на каждом устройстве, где инсталлирована виртуальная машина Java. Напомним, виртуальная машина Java — это «среда обработки», которая осуществляет запуск Java-приложения на любом устройстве, независимо от операционной системы. Благодаря этому п рограмма , написанная один раз на Java, может работать на Windows, Linux, MacOS без дополнительной адаптации под конкретную операционную систему.

Вся эта ситуация с кроссплатформенностью Java-программ стала возможно й б лагодаря байт-коду, который обрабатывает виртуальная машина. Поэтому понимание байт-кода для Java-программиста — это преимущество, которое поможет писать программный код еще лучше и эффективнее.

Байт-код Java

  • «-с» — дизасс е мблирует класс Java;
  • «-р» — раскрывает закрытые члены класса;
  • «-v» — показывает подробную информацию, например , стек или пул констант.

Байт-код Java: инструкции

  • для загрузки и сохранения;
  • для арифметических операций;
  • для преобразования типов;
  • для формирования и трансформирования объектов;
  • для управления стеком;
  • для операторов перехода;
  • для вызывания и возвращения методов;
  • для специфических задач.
  • префикс «I» означает «integer»;
  • «L» — «long»;
  • «S» — «short»;
  • «B» — «byte»;
  • «C» — «character»;
  • «F» — «float»;
  • «D» — «double»;
  • «A» — «reference»;
  • и др.

Байт-код Java и компиляторы

  • «Javac» — считается оригинальной компилирующей программой байт-кода Java;
  • «Jikes» — компилятор, созданный компанией IBM, при этом он запрограммирован на языке С++;
  • «Espresso» — компилятор, который был популярен в первых модификациях Java;
  • «GCJ» — функциональный компилятор, который способен формировать не только байт-код, но и машинный;
  • и др.
  • «Jruby», который формирует byte-код для JVM из Ruby;
  • «Jpython», который формирует byte-код из Python;
  • «MIDletPascal» — из Pascal;
  • и др.

Заключение

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

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

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Байт-код Java

Курс Байт-код Java

Данный курс для тех, кто уже знает синтаксис языка, но хотел бы разобраться в том, что из себя представляет чёрный ящик в виде JVM с её ByteCode, «руками потрогать» то, во что превращается ваш код после компиляции, научиться читать ByteCode и как следствие научиться анализировать программы даже без исходных кодов! Все это и многое другое в нашем новом курсе, который может быть востребован даже среди ведущих разработчиков.

Уже с первых уроков вы узнаете, что такое Java Bytecode и как его понимать, а к концу сможете делать много самостоятельных операций. Прохождение курса позволит вам лучше узнать платформу, с которой вы работаете, или же создать собственный язык программирования, легче проводить отладку и даже заняться низкоуровневой оптимизацией.

Следующий рекомендованный курс: «Java: Структуры данных» (https://ru.hexlet.io/courses/collections)

Программа курса

Продолжительность 5 часов

Модуль 0. Урок 0. Введение.

Вводный урок в котором мы рассказываем о том: что это за курс и для кого, что необходимо знать перед прохождением курса, какова структура курса (количество модулей и уроков), кто мы такие и почему делаем этот курс, место данного курса среди других.

Байт-код

Все языки можно условно разделить на компилируемые и интерпретируемые. В Java используется третий подход — байт-код. Исходный код Java преобразуется компилятором в байт-код (а не машинный код). A байт-код Java преобразуется в машинный код с помощью специального интерпретатора, называемого виртуальной машиной Java (Java Virtual Machine — JVM).

Рассмотрим более детально как работает Java:

Как работает Java фото

  1. Создается исходный документ (исходник) – файл c расширением .java.
  2. Исходник пропускается через компилятор, который проверяет код на ошибки и выдает конечный результат.
  3. Компилятор создает новый документ, закодированный с помощью байт-кода. Любое устройство, способное выполнять Java, сможет интерпретировать этот файл в такой формат, который сможет запустить. Скомпилированный байт-код не зависит от платформы.
  4. Виртуальная машина считывает и выполняет байт-код.

Презентацию с видео можно скачать на Patreon .

Знакомство с байт-кодами Java

Java-университет

В IntellijIDEA есть замечательная фича — показать байткод, позволяющая посмотреть как и в итоге JRE будет выполнять написанный код.(впрочем это также некоторая интерпретация компилятором машинного байткода для удобства чтения) Находится в View->Show Byte Code Что делает — анализирует скомпилированные .class — файлы. Описание команд можно найти по ссылке википедии.

Соответственно появилась идея разобрать байткоды для двух вариантов main-метода с инициализацией одинаковых строк, и попытаться прояснить почему они дают разные результаты: Вариант 1:(если сравнить str1==str2, то получаем false) public static void main(String[] args) < String str1 = new String("test"); String str2 = new String("test"); >Вариант 2:(если сравнить str3==str4, то получаем true) public static void main(String[] args) < String str3 = "test"; String str4 = "test"; >Байткод первого варианта(в квадратных скобках[] будет состояние стека после выполнения команды(вершина стека справа)): public static main([Ljava/lang/String;)V L0 LINENUMBER 5 L0 NEW java/lang/String //новая строка — кладем ссылку на класс «String «на вершину стека: [value_string] DUP //копируем ссылку на вершине стека: [value_string, value_string] LDC «test» //кладём в стек ссылку на «test» из constant pool(а если в нём еще нет ссылки на «test», //то она также остается в constant pool’e): [value_string, value_string, value_test] INVOKESPECIAL java/lang/String. (Ljava/lang/String;)V //вызов new для String с аргументами с вершины стека — //после вызова инициализирующего метода для стринг(и его внутренних манипуляций со стеком, //которые аналогично можно посмотреть в байткоде java.lang.String ) //- в стеке будет ссылка на проинициализированную строку: [value_result_string] //Почему для инициализации String(String) нужно три аргумента в стеке: //1)ссылка на входной аргумент 2)новая строка, 3)хешкод строки ASTORE 1 //сохраняем ссылку с вершины стека в локальную переменную(1) с вершины стека: [ ] L1 LINENUMBER 6 L1 NEW java/lang/String //аналогично первой строке DUP LDC «test» INVOKESPECIAL java/lang/String. (Ljava/lang/String;)V ASTORE 2 L2 LINENUMBER 7 L2 RETURN //return void — компилятор дописывает за нас если метод возвращает void L3 LOCALVARIABLE args [Ljava/lang/String; L0 L3 0 // список локальных переменных метода LOCALVARIABLE str3 Ljava/lang/String; L1 L3 1 // L1(метка где операции с локальной переменной) L3(метка где описание что это за локальная переменная) 1(номер локальной переменной) LOCALVARIABLE str4 Ljava/lang/String; L2 L3 2 // MAXSTACK = 3 //максимальная глубина стека метода MAXLOCALS = 3 //количество локальных переменных метода // //То есть сначала JRE будет выделять память при //вызове метода учитывая всю вложенность вызовов методов и new — инициализаций //(и если её не хватит — то всё вылетит с каким-нибудь OutOfMemory //эксепшном), а только потом будут производиться операции Байткод второго варианта: public static main([Ljava/lang/String;)V L0 LINENUMBER 5 L0 LDC «test» //берем ссылку на «test» из constant_pool и кладем на вершину стека: [value_test] ASTORE 1 //забираем ссылку с вершины стека в переменную(1) str1 : [ ] L1 LINENUMBER 6 L1 LDC «test» //берем ссылку на «test» из constant_pool и кладем на вершину стека: [value_test] ASTORE 2 //забираем ссылку с вершины стека в переменную(2) str2: [ ] L2 LINENUMBER 7 L2 RETURN //return void (который компилятор дописывает за нас как успешный конец метода) L3 LOCALVARIABLE args [Ljava/lang/String; L0 L3 0 //список локальных переменных, под которые выделяется память LOCALVARIABLE str1 Ljava/lang/String; L1 L3 1 //например: L1(метка где записан код) L3(метка где описан тип объекта и выделяется память) 1(локальный номер объекта) LOCALVARIABLE str2 Ljava/lang/String; L2 L3 2 // MAXSTACK = 1 //максимальная глубина стека для метода MAXLOCALS = 3 //количество локальных переменных метода

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *