Подтвердить что ты не робот

Char в байт? (Ява)

Как получилось:

char a = '\uffff'; //Highest value that char can take - 65535
byte b = (byte)a; //Casting a 16-bit value into 8-bit data type...! Isn't data lost here?
char c = (char)b; //Let get the value back
int d = (int)c;
System.out.println(d); //65535... how?

В принципе, я увидел, что char - 16 бит. Поэтому, если вы внесете его в byte, то почему данные не теряются? (Значение будет одинаковым после литья в int)

Заранее спасибо за ответ на этот маленький неосведомленный вопрос.: P

EDIT: Woah, выяснил, что мой исходный результат действительно сделал так, как ожидалось, но я только что обновил код выше. В принципе, персонаж выливается в байт, а затем возвращается обратно в char, и его исходное 2-байтовое значение сохраняется. Как это происходит?

4b9b3361

Ответ 1

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

char a = '\uffff';
byte b = (byte)a;  // b = 0xFF

Как вы отметили, это приводит к потере информации. Это считается сужение конверсии. Преобразование char в байт "просто отбрасывает все, кроме n бит младшего разряда".
Результат: 0xFFFF -> 0xFF

char c = (char)b;  // c = 0xFFFF

Преобразование байта в char считается специальным преобразованием . Он фактически выполняет ДВА преобразования. Во-первых, байт является расширенным SIGN (новые биты верхнего порядка копируются из старого знакового бита) в int (нормальное расширяющееся преобразование). Во-вторых, int преобразуется в char с сужением преобразования.
Результат: 0xFF -> 0xFFFFFFFF -> 0xFFFF

int d = (int)c;  // d = 0x0000FFFF

Преобразование a char в int считается расширяющимся преобразованием. Когда тип char расширяется до интегрального типа, он имеет ZERO-расширение (новые биты старшего порядка равны 0).
Результат: 0xFFFF -> 0x0000FFFF. При печати это даст вам 65535.

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

Ответ 2

Это расширение знака. Попробуйте \u1234 вместо \uffff и посмотрите, что произойдет.

Ответ 3

java byte подписан. это противодействует интуитивному. почти во всех ситуациях, когда используется байт, программистам понадобится вместо него беззнаковый байт. это, скорее всего, ошибка, если байт передается непосредственно int.

Это делает правильное преобразование практически во всех программах:

int c = 0xff & b ;

Эмпирически выбор подписанного байта является ошибкой.

Ответ 4

Несколько странных вещей, идущих на вашей машине. Посмотрите Спецификация языка Java, глава 4.2.1:

Значения интегральных типов целые числа в следующих диапазонах:

Для байта от -128 до 127 включительно

... отредактируйте другие...

Если ваша JVM соответствует стандартам, то ваш вывод должен быть -1.