Преобразование байтов и символов в Java

Если я преобразую символ в byte а затем вернусь к символу, этот персонаж загадочно исчезнет и станет чем-то другим. Как это возможно?

Это код:

 char a = 'È'; // line 1 byte b = (byte)a; // line 2 char c = (char)b; // line 3 System.out.println((char)c + " " + (int)c); 

До линии 2 все в порядке:

  • В строке 1 я мог напечатать «a» в консоли, и он отобразит «È».

  • В строке 2 я мог напечатать «b» в консоли, и будет показано -56, то есть 200, потому что байт подписан. А 200 – «È». Так что все по-прежнему хорошо.

Но что не так в строке 3? «c» становится чем-то другим, и программа печатает ? 65480 ? 65480 . Это совсем другое.

Что я должен написать в строке 3, чтобы получить правильный результат?

Символ на Java – это код Unicode, который обрабатывается как беззнаковое число. Поэтому, если вы выполняете c = (char)b вы получаете значение 2 ^ 16 – 56 или 65536 – 56.

Или, точнее, байт сначала преобразуется в целое число со знаком со значением 0xFFFFFFC8 с использованием расширения знака в расширяющемся преобразовании. Это, в свою очередь, затем сужается до 0xFFC8 при бросании на char , что переводит на положительное число 65480 .

Из спецификации языка:

5.1.4. Расширение и сужение примитивного преобразования

Во-первых, байт преобразуется в int посредством расширения примитивного преобразования (п. 5.1.2), а затем полученный int преобразуется в char путем сужения примитивного преобразования (п. 5.1.3).


Чтобы получить правильную точку, используйте char c = (char) (b & 0xFF) которая сначала преобразует значение байта b в положительное целое число 200 с помощью маски, обнуляя верхние 24 бита после преобразования: 0xFFFFFFC8 становится 0x000000C8 или положительным числом 200 в десятичных знаках.


Выше приведено прямое объяснение того, что происходит во время преобразования между byte , int и char примитивными типами.

Если вы хотите кодировать / декодировать символы из байтов, используйте Charset , CharsetEncoder , CharsetDecoder или один из удобных методов, таких как new String(byte[] bytes, Charset charset) или String#toBytes(Charset charset) . Вы можете получить набор символов (например, UTF-8 или Windows-1252) из StandardCharsets .

  • Ошибка кодирования с помощью HttpWebResponse
  • Ошибка «Unmappable character for encoding UTF-8»
  • Как получить значение ASCII строки в C #
  • В OS X Lion LANG не настроен на UTF-8, как его исправить?
  • Почему строка с кодировкой base64 имеет знак = в конце
  • C # Преобразование строки из UTF-8 в ISO-8859-1 (Latin1) H
  • Как найти кодировку по умолчанию или кодировку в Java?
  • Почему для кодировки base64 требуется заполнить, если входная длина не делится на 3?
  • В чем разница между кодировками utf8mb4 и utf8 в mysql?
  • Ruby on Rails 3, несовместимые кодировки символов: UTF-8 и ASCII-8BIT с i18n
  • Эффективный способ поиска кодировки любого файла
  • Давайте будем гением компьютера.