Где runtime Endianness определен в спецификации языка Java?

Кажется, что среда выполнения Java - это Big Endian, но я не могу найти ссылку на это, только для спецификации файла класса JVM.

Я ищу окончательное место в JLS (независимо от версии), в котором указано, что:

int value = 4096; // 0b0001 0000 0000 0000 = 0x10 00
                  //               \   /           |                             
int lastByte = value & 0xFF; //      |             |
assert lastByte == 0; // ---------------------------

а не lastByte == 16 (0x10)

ИЛИ, где указано, что это зависит от платформы / JVM.


person TWiStErRob    schedule 23.05.2014    source источник
comment
Возможный дубликат: stackoverflow.com/questions/362384/   -  person Software Engineer    schedule 23.05.2014
comment
Что заставляет вас думать, что порядок байтов вообще определяется в Java?   -  person Hot Licks    schedule 23.05.2014
comment
Кроме того, что вы могли бы сделать с этой информацией? (Я понимаю, что вам любопытно.)   -  person Sotirios Delimanolis    schedule 23.05.2014
comment
@EngineerDollery Не дублировать (это касается сети), я ищу определенное место, где примитивные целые числа Java определены как одно из них или определены как не определенные. @SotiriosDelimanolis Мне просто любопытно, потому что я видел много разных фреймворков, построенных на этом (в основном это что-то связано с Color.rgba()-подобными методами). @HotLicks, поэтому я поставил туда предложение OR.   -  person TWiStErRob    schedule 23.05.2014
comment
возможный дубликат порядка байтов виртуальной машины Java   -  person Drunix    schedule 23.05.2014
comment
Язык Java никоим образом не определяет и не зависит от порядка байтов. И в любых официальных интерфейсах, которые действительно раскрывают порядок байтов для внешнего мира, порядок байтов данных четко определен и часто может быть определен. И выполнение битового тиддлинга не имеет ничего общего с порядком байтов.   -  person Hot Licks    schedule 23.05.2014
comment
(Если необходимо, посмотрите спецификации JNI - нативный интерфейс на языке Си.)   -  person Hot Licks    schedule 23.05.2014
comment
Приведенный вами пример никоим образом не зависит от порядка байтов, поэтому вы даже не можете определить порядок байтов.   -  person Boann    schedule 23.05.2014


Ответы (1)


Это не столько вопрос языка, сколько виртуальной машины - вот почему он определен в Спецификации виртуальной машины Java, но не в Спецификации языка Java.

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

int value = 4111;                //   0x0000100F
int lastByte = value & 0xFF;     // & 0x000000FF
                                 // = 0x0000000F

Или Little-Endian:

int value = 4111;                //   0xF0010000
int lastByte = value & 0xFF;     // & 0xFF000000
                                 // = 0xF0000000

В обоих случаях результат одинаков (в любой из обеих форм).


Теперь можно было бы спорить о том, что 0x0000000F означает 15, что подразумевает прямой порядок байтов. Это, по крайней мере, неявно определено в определении лексической структуры в Раздел 3.10.1 JLS, Целочисленные литералы:

Наибольшие положительные шестнадцатеричные, восьмеричные и двоичные литералы типа int, каждый из которых представляет десятичное значение 2147483647 (2 ^ 31-1), соответственно:

  • 0x7fff_ffff,
  • 0177_7777_7777, и
  • 0b0111_1111_1111_1111_1111_1111_1111_1111

Кроме того, порядок следования байтов в основном важен для хранения и передачи данных, но это не языковые аспекты и облегчается такими вещами, как ByteOrder или на уровне API, как в метод DataOutputStream :: writeInt:

Записывает int в базовый выходной поток как четыре байта, сначала старший байт.


Единственная часть, в которой порядок байтов может влиять на семантику языка, - это операции сдвига. Но даже здесь это в основном вопрос интерпретации языка. Раздел 15.19 JLS об операторах сдвига утверждает:

Значение n ‹< s - это s битовых позиций, сдвинутых влево; это эквивалентно (даже если происходит переполнение) умножению на два в степени s.

Значение n ›› s представляет собой s битовых позиций, сдвинутых вправо с расширением знака. Результирующее значение составляет [n / 2s]. Для неотрицательных значений n это эквивалентно усечению целочисленного деления, вычисляемому оператором целочисленного деления /, на два до степени s.

В спецификации здесь указано, что существующие биты сдвигаются влево, и в то же время эта левая позиция является более значимой (однако можно также сказать, что << означает сдвиг вправо в мире Little-Endian ...)

person Marco13    schedule 23.05.2014
comment
Теперь можно спорить о том, что 0x0000000F означает 15, что подразумевает прямой порядок байтов. Тогда как 123.456f будет интерпретироваться на машине с прямым порядком байтов ?? - person Hot Licks; 24.05.2014
comment
@HotLicks Ну, я просто хотел предвидеть этот возможный аргумент, несмотря на то, что в любом случае он будет иметь смысл только для шестнадцатеричных литералов. Можно определить язык, где 0xF0000000 означает 15, но это просто не так, как в Java ... - person Marco13; 24.05.2014
comment
@ Marco13 Это было одно из моих подозрений, которое я не мог выразить словами. Спасибо, что выразили его словами! Еще одно уточнение: не правда ли, что если вы запустите свои примеры кода как соблюдаемый C ++ на разных архитектурах, это даст разные результаты? - person TWiStErRob; 25.05.2014
comment
@HotLicks f в 123.456f - это спецификатор одинарной точности с плавающей запятой, в 0x...F F - шестнадцатеричная цифра. - person TWiStErRob; 25.05.2014
comment
@TWiStErRob Я почти уверен, что HotLicks знает, что означает f ;-) Вероятно, это было просто нацелено на тот факт, что лексическая структура на самом деле ничего не говорит о порядке байтов базовой машины. Что касается вопроса о C ++: я не совсем уверен, что вы имеете в виду, но вы можете взглянуть на stackoverflow.com/questions/1041554 или похожие вопросы. - person Marco13; 25.05.2014
comment
@ Marco13, спасибо, этот вопрос все прояснил. Итак, моя точка зрения такова: порядок байтов имеет значение только тогда, когда вы отделяете многобайтовое примитивное значение с помощью доступа по указателю (очевидно, не относится к повседневной Java) или сериализации. Мне не хватало уровня абстракции между физическим представлением и побитовыми операциями. - person TWiStErRob; 25.05.2014