Java неявное преобразование интервала к байту

Я собираюсь начать работать над чем-то, требует байтов чтения и создания строк. Считанные байты представляют строки UTF-16. Таким образом, только для проверения вещей я хотел преобразовать простой массив байтов в кодировке UTF-16 к строке. Первые 2 байта в массиве должны представить порядок байтов и так должны быть или 0xff 0xfe или 0xfe 0xff. Таким образом, я пытался создать свой массив байтов следующим образом:

byte[] bytes = new byte[] {0xff, 0xfe, 0x52, 0x00, 0x6F, 0x00};

Но я получил ошибку, потому что 0xFF и 0xFE являются слишком большими для вписывания в байт (потому что байты подписываются в Java). Более точно ошибка состояла в том, что интервал не мог быть преобразован в байт. Я знаю, что мог просто явно преобразовать от интервала до байта с броском и достигнуть желаемого результата, но это не то, о чем мой вопрос.

Только для испытания чего-то я создал Строку и звонил, getBytes ("UTF-16") тогда распечатал каждый из байтов в массиве. Вывод немного сбивал с толку, потому что первые два байта были 0xFFFFFFFE 0xFFFFFFFF, сопровождаемым 0x00 0x52 0x00 0x6F. (Obvisouly, порядок байтов здесь отличается от того, что я пытался создать выше, но это не важно).

Используя этот вывод я решил попытаться создать свой массив байтов тот же путь:

byte[] bytes = new byte[] {0xffffffff, 0xfffffffe, 0x52, 0x00, 0x6F, 0x00};

И странно достаточно это хорошо работало. Таким образом, мой вопрос, почему Java позволяет целочисленное значение 0xFFFFFF80 или больше быть автоматически преобразованным в байт без явного броска, но что-нибудь равняется или больше, чем 0x80 требует явного броска?

9
задан DaveJohnston 20 December 2009 в 12:29
поделиться

5 ответов

Главное, что нужно запомнить, - это то, что int в Java является значением со знаком. Когда вы назначаете 0xffffffff (то есть 2 ^ 32 -1 ), это преобразуется в знаковое int со значением -1 - int не может на самом деле представлять такое большое число, как 0xffffffff , как положительное число.

Таким образом, для значений меньше 0x80 и больше 0xFFFFFF80 результирующее значение int находится в диапазоне от -128 до 127, что однозначно может быть представлено как байт . Все, что находится за пределами этого диапазона, не может быть и требует принудительного выполнения явного приведения, что приводит к потере данных в процессе.

10
ответ дан 4 December 2019 в 19:34
поделиться

Если вы используете число без подсказки (например, 1234L для длинного числа), компилятор принимает целое число. Значение 0xffffffff представляет собой целое число со значением -1 , которое может быть преобразовано в байт без предупреждения.

2
ответ дан 4 December 2019 в 19:34
поделиться

0xff то же самое, что и запись 0x000000ff , а не 0xffffffff . Так что это ваша проблема; целое число является положительным числом (255), но байт (при преобразовании бит в бит) будет отрицательным числом (-1). Но 0xffffffff равно -1 и как int , и как байт .

0
ответ дан 4 December 2019 в 19:34
поделиться

Поскольку 0xffffffff - это число -1, а -1 можно интерпретировать как байт.

0
ответ дан 4 December 2019 в 19:34
поделиться

Поскольку int подписаны, а 0xffffffff представляет -1, а 0xff представляет собой целое число со значением 255, которое не находится в диапазоне байтов -128 (0x80) +127 (0x7f).

0
ответ дан 4 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: