Unicode 4.0 в JDK 1.5
Една от новостите в JDK 1.5 е, че вече се поддържа доста по-широк набор от символи чрез приемане на стандарта Unicode 4.0
Естествено оказва се, че кодовете на всички тези символи не могат да се поберат в типа char, който е 16 битов. За това новите символи се кодират чрез заместваща двойка или code point – два поредни char-а, всеки от които се нарича code unit. Методът String.length продължава да връща броя char-ове в стринга. Но тъй като някои символи се кодират с 2 char-а, то String.length може би не е методът, който ви трябва ако търсите дължината стринга като брой символи. За това има въведен нов метод :
int codePointCount(int beginIndex, int endIndex)
Този метод връща броя code points или същински unicode символи като брои двойките за кодиране на новите символи като един.
Също така ако искате да вземете n-тия символ, String.charAt() няма да ви свърши работа – тъй като той би върнал n-тия char. За това има и нови методи :
int offset = str.offsetByCodePoints(0, 3);
int codePnt = str.codePointAt(offset);
Тук взимаме индекса на първия от единия или двата char-а, представящи 3-тия символ. И след това взимаме символа (един или два char-а) на дадената позиция.
И един пример за стринг, съдържащ един символ, който се кодира като двойка от char-ове :
String str = "\uD800\uDF30";
System.out.println("str: " + str);
System.out.println("str.length(): " + str.length());
System.out.println("str.codePointCount(0, str.length()): " + str.codePointCount(0, str.length()));
System.out.println("str.charAt(0): " + (int)str.charAt(0));
System.out.println("str.charAt(1): " + (int)str.charAt(1));
System.out.println("str.codePointAt(0): " + str.codePointAt(0));
System.out.println("str.codePointAt(1): " + str.codePointAt(1));
Извод : Ако работим с новите за Unicode 4.0 символи, трябва да сме много внимателни кои функции ползваме – досегашните, за които всеки символ е точно един char, или въведените от JDK 1.5 функции специално за работа с новите дву-char-ови символи. Излиза, че предимството на Java над C++, което дават изрично указаните в спецификацията на езика размери на всеки примитивен тип, вече става и недостатък.
Как това ще се отрази на интернационализацията, и как се съчетава евентуално с енкодинга на базите данни, ще видим тепърва.
Полезни ресурси:
- Спецификацията на класа String в JDK 1.5 API
- Strings – Core Java Technologies Technical Tips By John O’Conner


Хм, а защо не са пипнали старите функции да работят със самите символи (или codePoints, както ги наричат) и да направят ново api за побайтова работа? Не знам що си мисля, че всъщност много повече се използват string функциите на база брой символи, а не на база брой байтове…
Comment by Васил Колев — 19/8/2007 @ 11:53 am
Свикнала съм всеки евентуално проблемен дизайн да го оправдавам с “обратна съвместимост”. В случая обаче гледам малко странно точно на съвместимостта : не съм много сигурна, че приложение на Java 1.4 ще работи със стрингове както авторите са очаквали ако се добавят ресурсни файлове със символи от новата част от кодовата таблица.
Comment by Izida — 19/8/2007 @ 5:21 pm