Кодировка Unicode Java - PullRequest
       13

Кодировка Unicode Java

35 голосов
/ 28 марта 2010

Java char - 2 байта (максимальный размер 65 536), но есть 95,221 Unicode-символы.Означает ли это, что вы не можете обрабатывать определенные символы Unicode в приложении Java?

Это сводится к тому, какую кодировку символов вы используете?

Ответы [ 6 ]

35 голосов
/ 28 марта 2010

Вы можете справиться со всеми, если будете достаточно осторожны.

Java char - это кодовая единица UTF-16 . Для символов с кодовой точкой> 0xFFFF он будет закодирован с помощью 2 char s (суррогатная пара).

См. http://www.oracle.com/us/technologies/java/supplementary-142654.html о том, как обрабатывать эти символы в Java.

(Кстати, в Unicode 5.2 назначено 107 154 символов из 1114 112 слотов.)

14 голосов
/ 28 марта 2010

Java использует UTF-16 . Одна Java char может представлять только символы из базовой многоязычной плоскости . Другие символы должны быть представлены суррогатной парой из двух char с. Это отражено методами API, такими как String.codePointAt().

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

13 голосов
/ 14 апреля 2010

Чтобы добавить к другим ответам некоторые моменты, которые нужно запомнить:

  • A Java char всегда принимает 16 бит .

  • A Символ Unicode при кодировании в формате UTF-16 «почти всегда» (не всегда) 16 бит: это потому, что в кодировке Unicode более 64 КБ. Следовательно, символ Java НЕ является символом Юникода (хотя «почти всегда»).

  • «Почти всегда» выше означает первые 64K кодовых точек Unicode в диапазоне от 0x0000 до 0xFFFF ( BMP ), которые принимают 16 бит в кодировке UTF-16.

  • Не-BMP («редкий») символ Unicode представляется как два символа Java (суррогатное представление). Это относится также к буквальному представлению в виде строки: Например, символ U + 20000 записывается как "\ uD840 \ uDC00".

  • Corolary: string.length() возвращает количество символов java, а не символов Unicode. Строка, содержащая только один «редкий» символ Юникода (например, U + 20000), вернет length() = 2. То же самое относится к любому методу, который имеет дело с последовательностями символов.

  • Java обладает небольшим интеллектом для работы с не-BMP символами юникода в целом. Есть несколько служебных методов, которые обрабатывают символы как кодовые точки, представленные как целые, например: Character.isLetter(int ch). Это настоящие полностью Unicode методы.

3 голосов
/ 28 марта 2010

Ознакомьтесь с поддержкой Unicode 4.0 в статье J2SE 1.5 , чтобы узнать больше об уловках, изобретенных Sun для поддержки всех кодовых точек Unicode 4.0.

В итоге вы найдете следующие изменения для Unicode 4.0 в Java 1.5:

  • char - это кодовая единица UTF-16, а не кодовая точка
  • новые низкоуровневые API используют int для представления кодовой точки Unicode
  • API высокого уровня были обновлены для понимания суррогатных пар
  • предпочтение к API последовательности символов вместо методов на основе символов

Поскольку в Java нет 32-битных символов, я позволю вам судить, можем ли мы назвать эту хорошую поддержку Юникода.

2 голосов
/ 12 апреля 2012

Вот документация Oracle по символьным представлениям Unicode . Или, если хотите, более подробную документацию здесь .

Тип данных char (и, следовательно, значение, которое представляет собой объект Character инкапсуляции) основаны на оригинальной спецификации Unicode, которая определенные символы как 16-битные объекты фиксированной ширины. Юникод с тех пор стандарт был изменен, чтобы учесть символы, представление требует более 16 бит. Ассортимент юридического кодекса точки теперь от U + 0000 до U + 10FFFF, известные как скалярное значение Unicode. (См. Определение обозначения U + n в стандарте Unicode.)

Набор символов от U + 0000 до U + FFFF иногда называют как базовая многоязычная плоскость (BMP). Символы, чьи кодовые точки больше, чем U + FFFF, называются дополнительными символами. Ява 2 платформа использует представление UTF-16 в массивах символов и в Классы String и StringBuffer. В этом представлении дополнительный символы представлены в виде пары значений char, первый из диапазон высоких суррогатов, (\ uD800- \ uDBFF), второй из диапазон низких суррогатов (\ uDC00- \ uDFFF).

Значение символа, следовательно, представляет базовую многоязычную плоскость (BMP) кодовые точки, включая суррогатные кодовые точки или кодовые единицы Кодировка UTF-16. Значение int представляет все кодовые точки Unicode, включая дополнительные кодовые знаки. Нижний (наименее значимый) 21 биты int используются для представления кодовых точек Unicode и верхнего (самое значительное) 11 битов должны быть равны нулю. Если не указано иное, поведение по отношению к дополнительным персонажам и суррогатным Значения char следующие:

  • Методы, которые принимают только значение символа, не могут поддерживать дополнительные символы. Они относятся к значениям символов из суррогата диапазоны как неопределенные символы. Например, Character.isLetter ('\ uD840') возвращает false, хотя это значение, если за ним следует любое низкосуррогатное значение в строке представлять письмо.
  • Методы, принимающие значение типа int, поддерживают все символы Unicode, включая дополнительные символы. Например, Character.isLetter (0x2F81A) возвращает true, потому что значение кодовой точки представляет букву (идеография CJK).
1 голос
/ 28 марта 2010

Из документации OpenJDK7 для String :

Строка представляет строку в Формат UTF-16, в котором дополнительные символы представлены суррогатные пары (см. раздел Представления символов Unicode в Класс Character для более Информация). Значения индекса относятся к кодовые единицы, поэтому дополнительный персонаж использует две позиции в Строка.

...