Разница между cr lf, lf и типами разрывов строк cr?

Пример 2:

В этом примере для перевода данных использовался метод encode(). Это наиболее часто используемый и рекомендуемый способ преобразования строк Python в байты. Одна из основных причин – его легче читать. Синтаксис метода кодирования следующий:

# string.encode(encoding=encoding, errors=errors)

Строка, которую вы хотите преобразовать, называется строкой. Используемый вами метод кодирования называется «кодирование». Строка «Error» показывает сообщение об ошибке. UTF-8 стал стандартом со времен Python 3.

my_str = "sample code for conversion"
my_str_encoded = my_str.encode(encoding = 'UTF-8')
print(my_str_encoded)
for bytes in my_str_encoded:
print(bytes,end ='')

В качестве примера мы использовали строку my_str = “Sample code for conversion”. Мы использовали кодировку для преобразования после инициализации строки, а затем распечатали вывод строки. После этого мы распечатали отдельные байты следующим образом:

Стек операндов

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

Инструкция байт-кода и ее расширения нужны для перемещения значения, хранящегося в массиве переменных, в стек. Инструкция применяется для извлечения значений из стека и сохранения в массиве переменных. Существуют и другие инструкции, которые извлекают значения из стека для обработки.

Пример такого сценария — команда , которая извлекает два самых верхних значения из стека и складывает их вместе, а также инструкции вызова метода, которые извлекают самые верхние значения (число зависит от количества параметров, принятых методом) из стека, чтобы передать их в качестве аргументов методу. Если после выполнения команд будут получены результирующие значения, они будут помещены обратно в стек.

aload_0 //отправляет ссылку на непримитивное значение данных в индексе 0 массива переменныхiload_2 //отправляет значение int в индекс 4 массива переменныхiconst_3 //отправляет int 3 в стекiadd //добавляет два самых верхних значения int в стекistore_3 //выводит результат операции добавления и сохраняет в индексе 6 массива переменных

Как изменяется стек операндов и массив локальных переменных с помощью приведенных выше инструкций

Посмотрим в байт-код

Ради возможности вглядеться в байт-код, я написал простой Java-класс:

package demo;import java.util.ArrayList;import java.util.List;public class SimpleClass {    private List<Integer> evenNums;    public SimpleClass() {        evenNums = new ArrayList<>();    }    private boolean isEven(int num) {        return num % 2 == 0;    }    public void addEven(int num) {        if (isEven(num)) {            evenNums.add(num);        }    }}

Скомпилируем класс с помощью команды и посмотрим байт-код с помощью . Результат выглядит так:

Compiled from "SimpleClass.java"public class demo.SimpleClass {  private java.util.List<java.lang.Integer> evenNums;  public demo.SimpleClass();    Code:       0: aload_0       1: invokespecial #1                  // метод java/lang/Object."<init>":()V       4: aload_0       5: new           #2                  // класс java/util/ArrayList       8: dup       9: invokespecial #3                  // метод java/util/ArrayList."<init>":()V      12: putfield      #4                  // поле evenNums:Ljava/util/List;      15: return private boolean isEven(int);    Code:       0: iload_1       1: iconst_2       2: irem       3: ifne          10       6: iconst_1       7: goto          11      10: iconst_0      11: ireturn public void addEven(int);    Code:       0: aload_0       1: iload_1       2: invokespecial #5                  // Метод isEven:(I)Z       5: ifeq          22       8: aload_0       9: getfield      #4                  // Поле evenNums:Ljava/util/List;      12: iload_1      13: invokestatic  #6                  // Метод java/lang/Integer.valueOf:(I)Ljava/lang/Integer;      16: invokeinterface #7,  2            // Метод интерфейса java/util/List.add:(Ljava/lang/Object;)Z      21: pop      22: return}

Посмотрев на инструкции байт-кода, вы обнаружите несколько знакомых команд, включая и . Остальное, однако, может даже сбить с толку.

Пример 3:

В нашем третьем примере мы снова используем метод encode() для преобразования строк в байты. Это удобный способ конвертировать строки в байты.

my_str = "Learn about programing"
print(my_str)
print(type(my_str))
str_object = my_str.encode("utf-8")
print(str_object)
print(type(str_object))

Мы рассматриваем my_str=«Learn about programming» как источник, который нужно преобразовать в байты в приведенном выше коде. На следующем шаге мы превратили строку в байты с помощью метода encode(). До и после преобразования функция type() используется для проверки типа объекта. Здесь используется enc = utf-8.

Приведенный выше код сгенерировал следующий вывод.

Битовый порядок байтов

Нумерация битов — это концепция, аналогичная порядку байтов, но на уровне битов, а не байтов. Порядок следования битов или порядок следования битов на уровне битов относится к порядку передачи битов по последовательной среде. Битовый аналог little-endian (младший бит идет первым) используется в RS-232 , HDLC , Ethernet и USB . Некоторые протоколы используют обратный порядок (например, телетекст , I 2 C , SMBus , PMBus , SONET и SDH ), а использует один порядок для поля метки, а другой порядок для оставшейся части кадра. Обычно существует согласованное представление битов независимо от их порядка в байте, так что последний становится актуальным только на очень низком уровне. Одно исключение вызвано функцией некоторых циклических проверок избыточности для обнаружения всех пакетных ошибок до известной длины, которая будет испорчена, если порядок битов отличается от порядка байтов при последовательной передаче.

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

Пример

Пример порядка байтов

С прямым порядком байтов

Little-endian

Эти две диаграммы показывают, как два компьютера, использующие разный порядок байтов, хранят 32-битное (четырехбайтовое) целое число со значением 0x0A0B0C0D . В обоих случаях целое число разбивается на четыре байта, 0x0A , 0x0B , 0x0C и 0x0D , и байты сохраняются в четырех последовательных байтовых ячейках в памяти, начиная с ячейки памяти с адресом a , затем a + 1 , a + 2 и а + 3 . Разница между старшим и младшим порядком байтов заключается в порядке сохранения четырех байтов целого числа.

На левой диаграмме показан компьютер с прямым порядком байтов. При этом начинается сохранение целого числа с наиболее значимым байтом 0x0A по адресу a и заканчивается наименьшим байтом 0x0D по адресу a + 3 .

На правой диаграмме показан компьютер с прямым порядком байтов. Это начинает сохранение целого числа с наименьшим значащим байтом, 0x0D , по адресу a , и заканчивается самым значимым байтом, 0x0A , по адресу a + 3 .

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

Основы

Компьютерная память состоит из последовательности ячеек памяти (наименьших адресуемых единиц), обычно называемых байтами . Каждый байт идентифицируется и доступен в аппаратном и программном обеспечении по его адресу памяти . Если общее количество байтов в памяти равно n , то адреса нумеруются от 0 до n  — 1.

Компьютерные программы часто используют структуры данных или поля, которые могут состоять из большего количества данных, чем может быть сохранено в одном байте. В контексте этой статьи, где его тип не может быть произвольно сложным, «поле» состоит из последовательной последовательности байтов и представляет собой «простое значение данных», которым — по крайней мере потенциально — можно управлять с помощью одной единственной аппаратной инструкции . Адрес такого поля — это в основном адрес его первого байта.

Еще одним важным атрибутом байта, являющегося частью «поля», является его «значение». Эти атрибуты частей поля играют важную роль в последовательности доступа к байтам аппаратным обеспечением компьютера, точнее: низкоуровневыми алгоритмами, влияющими на результаты компьютерной инструкции.

Числа

Позиционные системы счисления (в основном основание 10, основание 2 или основание 256 в случае 8-битных байтов) являются преобладающим способом представления целочисленных данных и, в частности, манипулирования ими с помощью компьютеров. В чистом виде это справедливо для средних размеров неотрицательных целых чисел, например , типа данных C . В такой системе счисления значение цифры, которую она вносит в целое число, определяется не только ее значением как одной цифры, но также позицией, которую она занимает в полном числе, называемой ее значением. Эти позиции могут быть отображены в памяти двумя способами:

  • уменьшение числового значения с увеличением адресов памяти (или увеличением времени), известное как big-endian и
  • возрастание числового значения с увеличением адресов памяти (или увеличением времени), известное как little-endian .

Целочисленные данные, которые напрямую поддерживаются аппаратным обеспечением компьютера, имеют фиксированную ширину малой мощности 2, например 8 бит 1 байт, 16 бит ≙ 2 байта, 32 бита ≙ 4 байта, 64 бита ≙ 8 байтов, 128 бит ≙ 16 байт. Последовательность низкоуровневого доступа к байтам такого поля зависит от выполняемой операции. Для сложения , вычитания и умножения в первую очередь обращаются к младшему байту . Для деления и первую очередь обращаются к старшему байту . См. .

Для чисел с плавающей точкой см. .

Текст

Когда символьные (текстовые) строки должны сравниваться друг с другом, например, для поддержки какого-либо механизма , такого как сортировка , это очень часто делается лексикографически, когда один позиционный элемент (символ) также имеет позиционное значение. Лексикографическое сравнение означает почти везде: первый символ занимает высшее место — как в телефонной книге.

Целые числа, записанные в виде текста, всегда представляются в памяти первой старшей цифрой, что похоже на прямой порядок байтов, независимо от направления текста .

Сети

Во многих документах IETF RFC используется термин сетевой порядок , означающий порядок передачи битов и байтов по сети в сетевых протоколах . Среди прочего, исторический RFC 1700 (также известный как Интернет-стандарт STD 2) определил сетевой порядок для протоколов в наборе Интернет-протоколов как , отсюда и использование термина «сетевой порядок байтов» для байтов с прямым порядком байтов. порядок.

Однако не все протоколы используют порядок байтов с прямым порядком байтов в качестве сетевого порядка. Протокол Server Message Block (SMB) использует порядок байтов с прямым порядком байтов. В CANopen многобайтовые параметры всегда отправляются первым младшим байтом (с прямым порядком байтов). То же самое и с Ethernet Powerlink .

В Беркли Sockets API определяет набор функций для преобразования 16-битные и 32-битных чисел и из сетевого порядка байт: (хост-сети короткие) и (хост-сеть длиной) преобразует 16- битовые и 32-битные значения соответственно от машины ( хоста ) к сетевому порядку; и функции преобразования из сети в порядке хоста. Эти функции могут быть не оп на большой обратный порядок байт системы.

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

Интерпретация

Два способа просмотра новых строк, оба из которых являются самосогласованными , заключаются в том, что новые строки либо разделяют строки, либо завершают строки. Если символ новой строки считается разделителем, после последней строки файла не будет новой строки. В некоторых программах возникают проблемы с обработкой последней строки файла, если она не заканчивается символом новой строки. С другой стороны, программы, которые ожидают, что новая строка будет использоваться в качестве разделителя, будут интерпретировать последнюю новую строку как начало новой (пустой) строки. И наоборот, если символ новой строки считается символом конца, ожидается, что все текстовые строки, включая последнюю, будут завершены новой строкой. Если последняя последовательность символов в текстовом файле не является новой строкой, последняя строка файла может считаться неправильной или неполной текстовой строкой, или файл может считаться неправильно обрезанным.

В тексте, предназначенном в первую очередь для чтения людьми, использующими программное обеспечение, которое реализует функцию переноса слов , символ новой строки обычно необходимо сохранять только в том случае, если требуется разрыв строки, независимо от того, поместится ли следующее слово в той же строке, например, между абзацами. и в вертикальных списках. Поэтому в логике обработки текста и большинства текстовых редакторов новая строка используется как разрыв абзаца и известна как «жесткий возврат», в отличие от «мягкого возврата», которые динамически создаются для реализации переноса слов и могут изменяться с каждым экземпляр дисплея. Во многих приложениях существует отдельный управляющий символ, называемый «разрыв строки вручную», для принудительного разрыва строки внутри одного абзаца. Глиф для символа управления для жесткого возвращения, как правило, знак абзаца (¶), а также для ручного разрыва строки, как правило , возврат каретки стрелка (↵).

Массив локальных переменных

Массив локальных переменных, как следует из названия, нужен для хранения локальных переменных в методе. Также он хранит аргументы, которые принимает метод.

В массиве локальных переменных с индексацией от нуля первые индексы используются для хранения аргументов метода. После того, как они будут сохранены, в массив сохранятся другие локальные переменные. Если метод — не статический, а создаёт экземпляры, нулевой индекс будет зарезервирован для хранения ссылки , которая указывает на экземпляр объекта для вызова метода.

Определим два метода: один статический и один метод экземпляра, но схожие во всем остальном.

public String sayHello(int num, String name){    String hello = "Hello, " + name;    return hello;}public static String sayHello(int num, String name){    String hello = "Hello, " + name;    return hello;}

Локальные массивы переменных для этих методов будут выглядеть следующим образом:

Локальные массивы переменных во фреймах метода JVM

Пример 1:

Чтобы преобразовать строку в байты, мы можем использовать встроенный в Python класс Bytes: просто укажите строку в качестве первого аргумента функции Object() { } класса Bytes, а затем укажите кодировку. Изначально у нас есть строка с названием «my_str». Мы преобразовали эту конкретную строку в байты.

my_str = "welcome to Python"
str_one = bytes(my_str, 'utf-8')
str_two = bytes(my_str, 'ascii')
print(str_one,'\n')
for byte in str_one:
print(byte, end='')
print('\n')
for byte in str_two:
print(byte,end='')

Этот подход, как видите, преобразовал строку в серию байтов. Обратите внимание, что эта функция преобразует объекты в неизменяемые байты; если вам нужен изменяемый метод, используйте вместо него метод bytearray(). Элемент был создан в текстовом формате, который легко читается, но данные, которые он содержит, указаны в байтах. Вот результат реализации приведенного выше кода

Тип данных JVM

Java статически типизирована, и это влияет на дизайн инструкций байт-кода, так что инструкция ожидает, что она будет работать с определенным типом значения. Например, будет несколько инструкций по добавлению двух чисел: iadd, ladd, fadd, dadd. Операнды, которые они ожидают, являются int, long, float и double. Большинство байт-кодов имеют такую ​​особенность, что они выполняют одну и ту же функцию в разных формах, в зависимости от типа операнда. Типы данных, определенные JVM, включают в себя:

  1. Основной тип:
    • Типы значений: байты (8 бит), короткие (16 бит), целые (32 бита), длинные (64-битные), char (16-битный беззнаковый Unicode), плавающие (32-битная IEEE 754 с плавающей запятой одинарной точности) ), двойной (64-битная IEEE 754 с плавающей запятой двойной точности)
    • Логический тип
    • Тип указателя: указатель инструкции.
  2. Тип ссылки:
    • категория
    • массив
    • интерфейс

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

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

Простой пример

2. Отображение байтового кода основной функции

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

3. Процесс выполнения инструкции байт-кода

Следующий анализПроцесс запуска промежуточного кода. Здесь число перед каждой инструкцией является смещением инструкции в регистре.

Поместите целую константу 1 в стек операндов. Вот небольшое расширение. Если вы поместите константу с плавающей точкой 2 в стек, команда nameПожалуйста, обратитесь к следующей главе для подробных типов инструкций и значенийИнструкции байт-кода Java。

Порядковый номер в пуле вызывающих константСтатический метод, здесь он называется Integer.valueOf (), что означает, что тип int упакован и становится типом Integer.

Поместите первый операнд в стек по индексу 1 (целочисленное значение) и сохраните его в локальной переменной, которая эквивалентна переменной a.

Поместите int константу 2 в стек операндов

Порядковый номер в пуле вызывающих константСтатический метод, здесь он называется Integer.valueOf (), что означает, что тип int упакован и становится типом Integer.

Поместите первый операнд в стек с индексом 2 (целочисленное значение) и сохраните его в локальной переменной, которая эквивалентна переменной b.

Загрузите значение int из локальной переменной по индексу 1 и поместите его в стек операндов

Порядковый номер в пуле вызывающих константМетод экземпляра, здесь называется метод Integer.intValue ()

Загрузите значение int из локальной переменной по индексу 1 и поместите его в стек операндов

Порядковый номер в пуле вызывающих константМетод экземпляра, здесь называется метод Integer.intValue ()

Первые два значения int в стеке операндов выталкиваются из стека и добавляются, а результат сложения помещается в стек операндов.

Порядковый номер в пуле вызывающих константСтатический метод, здесь называется метод Integer.valueOf ()

Поместите первый операнд в стек по индексу 3 (целочисленное значение) и сохраните его в локальной переменной, эквивалентной переменной c.

Конец метода

Обратный и частичный перевод строки

RI , ( U + 008D REVERSE LINE FEED, ISO / IEC 6429 8D, decimal 141) используется для перемещения позиции печати на одну строку назад (путем обратной подачи бумаги или перемещения курсора дисплея на одну строку вверх), чтобы другие символы может быть напечатан поверх существующего текста. Это может быть сделано для того, чтобы сделать их более жирными, или для добавления подчеркивания, зачеркивания или других символов, например диакритических знаков .

Аналогичным образом, PLD ( U + 008B ЧАСТИЧНАЯ СТРОКА ВПЕРЕД, десятичное число 139) и PLU ( U + 008C ЧАСТИЧНОЕ НАЗАД, десятичное число 140) могут использоваться для перемещения вперед или назад позиции печати текста на некоторую долю вертикального межстрочного интервала (обычно половину ). Их можно использовать в комбинации для нижних индексов (путем перехода вперед, а затем в обратном направлении) и верхних индексов (путем поворота и последующего продвижения), а также может быть полезно для печати диакритических знаков.

Вызов метода

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

3. Подробный процесс выполнения инструкции

Выше приведен байт-код основного метода и метода calc. Поскольку инструкции основного метода очень похожи на предыдущий пример, единственное отличие состоит в том, чтоВыполняется методом calc и возвращает. Основной метод здесь не повторяется, и процесс выполнения метода calc в основном объясняется далее.

Поместите первый параметр в методе в стек

Преобразовать тип int в тип double

Серийный номер пула константДлинная константа типа помещается из пула констант в верхнюю часть стека (широкий индекс) Вызовите статический метод: Math.pow :() и поместите результат в верхнюю часть стека.

Приведенная выше инструкция такая же, как и предыдущая, квадратная операция

Добавьте результат и результат2 и нажмите на вершину стека

Вызовите метод Math.sqrt ()

Конвертировать двойной тип в тип int

Возвращает числовое значение типа int

5 ответов

Лучший ответ

— это константа, которую вы ищете — http: //msdn.microsoft.com/en-us/library/system.environment.newline.aspx, который предоставит комбинацию для конкретной среды, которую большинство программ в данной ОС будет рассматривать как «следующую строку текста».

На практике большинство текстовых инструментов обрабатывают все варианты, которые включают , как «новую строку», и вы можете просто использовать ее в своем тексте . Особенно, если вы пытаетесь создать строки многострочного формата, такие как . Если вы создаете текст с конкатенацией строк, подумайте об использовании . В любом случае убедитесь, что инструменты, которые вы используете, понимают вывод так, как вы хотите, и вам может потребоваться, например, всегда использовать независимо от платформы, если выбранный вами редактор не может правильно открывать файлы в противном случае .

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

В разделе Разница между \ n и \ r?

Историческую справку см. В разделе Разница между \ n и \ r?

71

Alexei Levenkov
28 Сен 2018 в 02:51

Возврат каретки перемещает курсор в начало текущей строки. Перевод строки вызывает переход на следующую строку и возможно начало следующей строки; Это часть, зависящая от платформы, которую Алексей отмечает выше (в системе * nix дает вам и возврат каретки, и новую строку, в Windows — нет)

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

12

Brian Roach
8 Мар 2011 в 02:46

Это зависит от того, где вы показываете текст. Например, в консоли или текстовом поле \ n будет достаточно. На RichTextBox я думаю, вам нужно и то, и другое.

1

kprobst
8 Мар 2011 в 02:43

Я знаю, что это немного устарело, но любой, кто наткнется на эту страницу, должен знать, что есть разница между \ n и \ r \ n.

\ R \ n дает конец строки CRLF, а \ n дает символ конца строки LF. В целом для глаза разницы очень мало.

Создайте .txt из строки, а затем попробуйте открыть в блокноте (обычно, а не в блокноте ++), и вы заметите разницу

Выше используется «CRLF», а ниже показано, как будет выглядеть «только LF» (есть символ, который не виден там, где отображается LF).

Если необходимо исправить концы строк, а размер файла достаточно мал, вы можете изменить концы строк в NotePad ++ (или вставить в слово, а затем обратно в «Блокнот» — хотя это сделает только CRLF).

Это может привести к тому, что некоторые функции, которые читают эти файлы, потенциально больше не будут работать (приведенные примеры строк взяты из GP Prescribing data — England. Файл изменился с конца строки CRLF на конец строки LF). Это остановило выполнение задания SSIS и завершилось ошибкой, так как не удалось прочитать окончания строки LF.

Источник информации о конце строки:

Надеюсь, это поможет кому-то в будущем :) CRLF = Windows, LF или CF из систем на базе Unix (Linux, MacOS и т. Д.)

1

Mex
16 Апр 2019 в 11:14

Это всегда хорошая идея, и хотя это не всегда требуется, стандарт Windows должен включать и то, и другое.

\ n на самом деле представляет собой перевод строки или число 10, а канонический перевод строки означает просто «перемещение вниз на одну строку» на терминалах и телетайпах.

\ r представляет собой CR, возврат каретки или число 13. В Windows, Unix и большинстве терминалов CR перемещает курсор в начало строки. (Это не относится к 8-битным компьютерам: большинство из них переходят на следующую строку с CR.)

В любом случае, некоторые процессы, такие как текстовая консоль, могут автоматически добавлять CR при отправке LF. Однако, поскольку CR просто перемещается в начало строки, нет ничего плохого в том, чтобы отправить CR дважды.

С другой стороны, диалоговые окна, текстовые поля и другие элементы отображения требуют, чтобы CR и LF правильно начинали новую строку.

Поскольку на самом деле нет недостатков в отправке обоих, и в некоторых ситуациях требуются оба, простейшая политика — использовать оба, если вы не уверены.

TomXP411
30 Янв 2021 в 04:19

Деконструкция байт-кода

Все не так страшно, как кажется. Попробуем деконструировать байт-код шаг за шагом. Начнем с самого простого метода — .

private boolean isEven(int num) { return num % 2 == 0;}

Вот его байт-код:

private boolean isEven(int); Code: 0: iload_1 1: iconst_2 2: irem 3: ifne 10 6: iconst_1 7: goto 11 10: iconst_0 11: ireturn
  1. Во-первых, инструкция помещает значение массива локальных переменных с индексом 1 в стек операндов. Поскольку метод является методом экземпляра, ссылка на него хранится в нулевом индексе. Тогда легко понять, что значение, хранящееся в индексе 1, на самом деле будет принятым значением параметра .
  2. помещает значение 2 в верхнюю часть стека операндов.
  3. Инструкция применяется для нахождения остатка от деления между двумя числами. Это инструкция, которая представляет логику оператора . Она извлекает два самых верхних значения в стеке и помещает результат обратно в стек.
  4. Команда сообщает JVM перейти к инструкции с заданным смещением (в данном случае — 10), если значение, обрабатываемое командой, не равно 0. Для реализации этой логики команда берет верхний элемент стека. Если переданное число было четным, то верхний элемент будет равен 0, и в этом случае JVM получает команду перейти к инструкции с индексом 6. Однако, если значение стека не равно нулю, что происходит, когда число нечетное, JVM переходит к инструкции с индексом 10.
  5. помещает значение в стек. Это происходит только в том случае, если результат равен 1. Здесь 1 представляет логическое значение .
  6. говорит JVM перейти к инструкции, приведенной в смещении, что в данном случае равно 11. Инструкция применяется для перехода с одного места в таблице инструкций на другое.
  7. помещает в стек значение 0. Эта инструкция идет в дело, когда условие оказывается ложным. Переданное значение 0 действует как логическое значение . Инструкции 3, 6, 7 обрабатывают случай, когда условие истинно.
  8. возвращает значение в верхней части стека.

Здесь важно отметить еще одно: индексы, заданные инструкциям байт-кода — как видим, они не увеличиваются на единицу для каждой новой инструкции. Число перед инструкцией указывает на индекс ее начального байта

А любой байт-код состоит из однобайтовых опкодов, за которыми следует ноль или более операндов

Число перед инструкцией указывает на индекс ее начального байта. А любой байт-код состоит из однобайтовых опкодов, за которыми следует ноль или более операндов.

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

В байт-коде есть другие инструкции, такие как , и , которые в свою очередь являются инструкциями вызова метода.

Вывод

Надеюсь, вам удалось узнать кое-что новое о том, как работает байт-код Java. С этим более четким знанием вы сможете лучше писать код. Можете даже поэкспериментировать с самим байт-кодом во время выполнения программы, воспользовавшись такими библиотеками, как ASM.

  • Сборка мусора в Java: что это такое и как работает в JVM
  • 9 советов, как выделиться среди Java-разработчиков
  • Состояния потоков в Java

Читайте нас в Telegram, VK и

Этимология

Дэнни Коэн ввел в информатику термины с прямым порядком байтов и прямым порядком байтов для упорядочения данных в заметке об эксперименте в Интернете, опубликованной в 1980 году.

Прилагательное endian возникло в трудах англо-ирландского писателя 18 века Джонатана Свифта . В романе «Путешествия Гулливера» 1726 года он изображает конфликт между сектами лилипутов, разделенных на те, кто ломает скорлупу вареного яйца с большого конца или с маленького конца. Он назвал их Big-Endians и Little-Endians . Коэн явно указывает связь с « Путешествиями Гулливера» в приложении к своей заметке 1980 года.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: