A Java char
est 2 octets (taille maximale de 65 536) mais il y a 95 221 caractères Unicode. Cela signifie-t-il que vous ne pouvez pas gérer certains caractères Unicode dans une application Java?
Est-ce que cela se résume au codage de caractères que vous utilisez?
Vous pouvez tous les gérer si vous faites assez attention.
char
de Java est un nité de code UTF-16 . Pour les caractères avec point de code> 0xFFFF, il sera codé avec 2 char
s (une paire de substitution).
Voir http://www.Oracle.com/us/technologies/Java/supplementary-142654.html pour savoir comment gérer ces caractères en Java.
(BTW, dans Unicode 5.2 il y a 107.154 caractères assignés sur 1.114.112 emplacements.)
Java utilise TF-16 . Un seul Java char
ne peut représenter que des caractères du plan multilingue de base . Les autres caractères doivent être représentés par un paire de substitution de deux char
s. Ceci est reflété par des méthodes API telles que String.codePointAt()
.
Et oui, cela signifie que beaucoup de code Java se cassera d'une manière ou d'une autre lorsqu'il est utilisé avec des caractères en dehors du plan multilingue de base.
Pour ajouter aux autres réponses, quelques points à retenir:
A Java char
prend toujours 16 bits .
Un caractère Unicode , lorsqu'il est codé en UTF-16, prend "presque toujours" (pas toujours) 16 bits: c'est parce qu'il y a plus de 64K caractères unicode . Par conséquent, un Java char n'est PAS un caractère Unicode (bien que "presque toujours" l'est).
"Presque toujours", ci-dessus, signifie les 64K premiers points de code d'Unicode, compris entre 0x0000 et 0xFFFF ( BMP ), qui prennent 16 bits en UTF-16 codage.
Un caractère Unicode non BMP ("rare") est représenté par deux Java (représentation de substitution). s'applique également à la représentation littérale sous forme de chaîne: Par exemple, le caractère U + 20000 s'écrit "\ uD840\uDC00".
Corolary: string.length()
renvoie le nombre de caractères Java, pas de caractères Unicode. Une chaîne qui n'a qu'un seul caractère Unicode "rare" (par exemple U + 20000) retournera length() = 2
. La même considération s'applique à toute méthode qui traite des séquences de caractères.
Java a peu d'intelligence pour traiter les caractères unicode non BMP dans leur ensemble. Il existe certaines méthodes utilitaires qui traitent les caractères comme des points de code, représentés comme des entiers, par exemple: Character.isLetter(int ch)
. Ce sont les vraies méthodes entièrement Unicode.
Consultez l'article Prise en charge d'Unicode 4.0 dans J2SE 1.5 pour en savoir plus sur les astuces inventées par Sun pour prendre en charge tous les points de code Unicode 4.0.
En résumé, vous trouverez les modifications suivantes pour Unicode 4.0 dans Java 1.5:
char
est une unité de code UTF-16, pas un point de code- les nouvelles API de bas niveau utilisent un
int
pour représenter un point de code Unicode- les API de haut niveau ont été mises à jour pour comprendre les paires de substitution
- une préférence pour les API de séquence de caractères plutôt que pour les méthodes basées sur les caractères
Puisque Java n'a pas de caractères 32 bits, je vous laisse juger si nous pouvons appeler ce bon support Unicode.
Voici la documentation d'Oracle sur Représentations de caractères Unicode . Ou, si vous préférez, un documentation plus complète ici .
Le type de données char (et donc la valeur encapsulée par un objet Character) est basé sur la spécification Unicode d'origine, qui définissait les caractères comme des entités 16 bits de largeur fixe. La norme Unicode a depuis été modifiée pour autoriser les caractères dont la représentation nécessite plus de 16 bits. La plage de points de code légaux est désormais U + 0000 à U + 10FFFF, connue sous le nom de valeur scalaire Unicode. (Reportez-vous à la définition de la notation U + n dans la norme Unicode.)
L'ensemble de caractères de U + 0000 à U + FFFF est parfois appelé le plan multilingue de base (BMP). Les caractères dont les points de code sont supérieurs à U + FFFF sont appelés caractères supplémentaires. La plate-forme Java 2 utilise la représentation UTF-16 dans les tableaux de caractères et dans les classes String et StringBuffer. Dans cette représentation, les caractères supplémentaires sont représentés comme une paire des valeurs de caractères, la première de la plage des substituts élevés, (\ uD800-\uDBFF), la seconde de la plage des substituts faibles (\ uDC00-\uDFFF).
Une valeur char représente donc les points de code du plan multilingue de base (BMP), y compris les points de code de substitution ou les unités de code du codage UTF-16. Une valeur int représente tous les points de code Unicode, y compris les points de code supplémentaires. Les 21 bits inférieurs (les moins significatifs) de int sont utilisés pour représenter les points de code Unicode et les 11 bits supérieurs (les plus significatifs) doivent être nul. Sauf indication contraire, le comportement en ce qui concerne les caractères supplémentaires et les valeurs de substitution est le suivant:
- Les méthodes qui n'acceptent qu'une valeur char ne peuvent pas prendre en charge les caractères supplémentaires. Ils traitent les valeurs de caractères des plages de substitution comme des caractères non définis. Par exemple, Character.isLetter ('\ uD840') renvoie false, même si cette valeur spécifique si elle est suivie d'une valeur de substitution faible dans une chaîne représenterait une lettre.
- Les méthodes qui acceptent une valeur int prennent en charge tous les caractères Unicode, y compris les caractères supplémentaires. Par exemple, Character.isLetter (0x2F81A) renvoie vrai car la valeur du point de code représente une lettre (un idéogramme CJC).
De la documentation OpenJDK7 pour String :
Une chaîne représente une chaîne au format UTF-16 dans laquelle les caractères supplémentaires sont représentés par des paires de substitution (voir la section Représentations de caractères Unicode dans la classe Caractère pour plus d'informations). Les valeurs d'index se réfèrent aux unités de code de caractère, donc un caractère supplémentaire utilise deux positions dans une chaîne.