Немного предыстории: когда в 1995 году появилась Java, тип char
был основан на исходной спецификации " Unicode 88 ", которая была ограничена 16 битами. Год спустя, когда был внедрен Unicode 2.0, была введена концепция суррогатных символов, выходящая за пределы 16-битного ограничения.
Java внутренне представляет все String
с в формате UTF-16. Для кодовых точек, превышающих U + FFFF, кодовая точка представлена суррогатной парой, т. Е. Двумя char
s, причем первая - это высокосуррогатная кодовая единица (в диапазоне \ uD800- \ uDBFF), вторая - код с низким суррогатным кодом (в диапазоне \ uDC00- \ uDFFF).
С самых первых дней все основные Character
методы основывались на предположении, что кодовая точка может быть представлена в одном char
, так что именно так выглядят сигнатуры методов. Я предполагаю сохранить обратную совместимость, которая не изменилась, когда появился Unicode 2.0, и при работе с ними необходима осторожность. Цитировать из документации Java :
- Методы, которые принимают только значение символа, не могут поддерживать дополнительные символы. Они обрабатывают значения символов из суррогатных диапазонов как неопределенные символы. Например, Character.isLetter ('\ uD840') возвращает false, даже если это конкретное значение, если за ним следует любое низкосуррогатное значение в строке, будет представлять букву.
- Методы, принимающие значение типа int, поддерживают все символы Unicode, включая дополнительные символы. Например, Character.isLetter (0x2F81A) возвращает true, поскольку значение кодовой точки представляет букву (идеограф CJK).
Преобразование char
в int
, как в примере, работает нормально.