Java char
2 байта (макс. размер 65 536), но существует 95 221 символ Unicode. Это означает, что Вы не можете обработать определенные символы Unicode в JAVA-приложении?
Это сводится, для какой кодировки символов Вы используете?
Вы справитесь со всеми, если будете достаточно осторожны.
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 слотов.)
Посмотрите статью о поддержке Unicode 4.0 в J2SE 1.5 чтобы узнать больше о хитростях, изобретенных Sun для обеспечения поддержки всех кодовых точек Unicode 4.0.
Таким образом, вы обнаружите следующие изменения для Unicode 4.0 в Java 1.5:
char
- это кодовая единица UTF-16, а не кодовая точка- новые низкоуровневые API-интерфейсы используют
int
для представления кодовой точки Unicode- API высокого уровня были обновлены для понимания суррогатных пар
- предпочтение отдается API последовательности символов вместо методов на основе char
Поскольку в Java нет 32-битных chars, я позволю вам судить, можем ли мы назвать эту хорошую поддержку Unicode.
Java использует UTF-16 . Один символ Java char
может представлять только символы из базовой многоязычной плоскости . Другие символы должны быть представлены суррогатной парой из двух char
s. Это отражено в методах API, таких как String.codePointAt ()
.
И да, это означает, что большая часть кода Java будет тем или иным образом нарушена при использовании с символами за пределами базовой многоязычной плоскости.
Из документации OpenJDK7 для String :
String представляет строку в формате UTF-16 в котором дополнительные символы представлены суррогатными парами (дополнительную информацию см. в разделе Представления символов Юникода в классе символов). Значения индекса относятся к единицам кода символа , поэтому дополнительный символ использует две позиции в строке .
Чтобы добавить к другим ответам, некоторые моменты, которые следует запомнить:
A Java char
всегда занимает 16 бит .
Символ Юникода , когда он закодирован как UTF-16, «почти всегда» (не всегда) принимает 16 бит: это потому, что существует более 64 КБ символов Юникода. Следовательно, Java char НЕ является символом Unicode (хотя «почти всегда»).
«Почти всегда» выше означает первые 64 КБ кодовых точек Unicode в диапазоне от 0x0000 до 0xFFFF ( BMP ), которые занимают 16 бит в кодировке UTF-16.
Не-BMP («редкий») символ Unicode представлен как два символа Java (суррогатное представление). Это относится также к буквальному представлению в виде строки: Например, символ U + 20000 записывается как «\ uD840 \ uDC00».
Следствие: string.length ()
возвращает количество символов Java, а не символов Unicode. Строка, содержащая только один «редкий» символ Юникода (например, U + 20000), вернет length () = 2
. То же самое относится к любому методу, который имеет дело с последовательностями символов.
Java в целом не обладает достаточным интеллектом для работы с символами Unicode, отличными от BMP. Есть несколько служебных методов, которые обрабатывают символы как кодовые точки, представленные как целые числа, например: Character.isLetter (int ch)
.Это настоящие методы, полностью поддерживающие Unicode.