Ali*_*itt 27 java character character-encoding
我试图找到术语"字符","代码点"和"代理"的解释,虽然这些术语不仅限于Java,但如果存在任何特定于语言的差异,我希望解释为它与Java有关.
我发现了一些关于字符和代码点之间差异的信息,字符是为人类用户显示的内容,代码点是编码特定字符的值,但我对代理人一无所知.什么是代理人,他们与角色和代码点有什么不同?我对字符和代码点有正确的定义吗?
在另一个关于将字符串作为字符数组逐步执行的线程中,提示此问题的具体注释是"请注意,此技术为您提供字符,而不是代码点,这意味着您可能会获得代理." 我真的不明白,而不是就一个5年前的问题创建一系列评论,我认为最好在新问题中要求澄清.
Cep*_*pod 26
要在计算机中表示文本,您必须解决两件事:首先,您必须将符号映射到数字,然后,您必须用字节表示这些数字的序列.
甲码点是一个数字,识别符号.为符号分配数字的两个众所周知的标准是ASCII和Unicode.ASCII定义128个符号.Unicode目前定义109384个符号,超过2 16个符号.
此外,ASCII指定数字序列表示每个数字一个字节,而Unicode指定几种可能性,例如UTF-8,UTF-16和UTF-32.
当您尝试使用每个字符使用少于表示所有可能值(例如UTF-16,使用16位)所需的位数的编码时,您需要一些解决方法.
因此,代理是16位值,表示不符合单个双字节值的符号.
Java使用UTF-16.
特别是,char(字符)是包含UTF-16值的无符号双字节值.
如果您想了解有关Java和Unicode的更多信息,我可以推荐这篇新闻通讯:第1 部分,第2部分
nos*_*sid 15
您可以在Javadoc中找到类java.lang.Character的简短说明:
Unicode字符表示
的
char数据类型(以及因此一个值Character对象封装)是基于原始Unicode规范,其定义字符为固定宽度的16位实体.此后,Unicode标准已更改为允许表示形式需要16位以上的字符.法律的范围内的代码点,现在是U+0000到U+10FFFF被称为Unicode标值.[..]来自
U+0000to 的字符集U+FFFF有时被称为基本多语言平面(BMP).代码点大于的字符U+FFFF称为增补字符.Java平台在char数组String和StringBuffer类中使用UTF-16表示.在此表示中,补充字符表示为一对char值,第一个来自高代理范围(\ uD800-\uDBFF),第二个来自低代理范围(\ uDC00-\uDFFF).
换一种说法:
甲代码点通常表示单个字符.最初,类型的值char与Unicode代码点完全匹配.这种编码也称为UCS-2.
因此,char定义为16位类型.但是,目前Unicode中有超过2 ^ 16个字符.为了支持整个字符集,编码从固定长度编码UCS-2变为可变长度编码UTF-16.在此编码中,每个代码点由单个char或两个chars表示.在后一种情况下,两个字符称为代理对.
UTF-16以这样的方式定义,即如果所有代码点都低于2 ^ 14,则使用UTF-16和UCS-2编码的文本之间没有区别.这意味着,char可以用来表示一些但不是所有的字符.如果一个字符不能在一个字符内表示char,则该术语char具有误导性,因为它仅用作16位字.
代码点通常是指Unicode代码点.Unicode术语表说:
Codepoint(1):Unicode代码空间中的任何值; 也就是说,整数范围从0到10FFFF16.
在Java中,character(char)是无符号的16位值; 即0到FFFF.
如您所见,有更多的Unicode代码点可以表示为Java字符.然而,Java需要能够使用所有有效的Unicode代码点来表示文本.
Java处理这个问题的方法是将大于FFFF的代码点表示为一对字符(代码单元); 即代理对.这些编码一个Unicode编码点比FFFF较大为一对16位值.这使用了以下事实:Unicode代码空间的子范围(即D800到U + DFFF)被保留用于表示代理对.技术细节在这里.
Java正在使用的编码的正确术语是UTF-16编码表单.
您可能会看到的另一个术语是代码单元,它是特定编码中使用的最小代表单位.在UTF-16中,代码单元是16位,对应于Java char.其他编码(例如UTF-8,ISO 8859-1等)具有8位代码单元,而UTF-32具有32位代码单元.
角色这个词有很多含义.它意味着不同背景下的各种事物.Unicode术语表为Character提供了4个含义,如下所示:
字符.(1)具有语义价值的书面语言的最小组成部分; 指的是抽象的意义和/或形状,而不是特定的形状(参见字形),但在代码表中,某种形式的视觉表现对于读者的理解是必不可少的.
字符.(2)抽象字符的同义词.(抽象字符.用于组织,控制或表示文本数据的信息单元.)
字符.(3)Unicode字符编码的基本编码单位.
字符.(4)中国出身的表意文字要素的英文名称.[见表意文字(2).]
然后是Java对字符的特定含义.
简单的说:
\nCode unit需要char2 个字节,编码为UTF-16,每个字符不一定代表一个real world character。Code point始终是 a real world character,它可能包含 1 或 2 Code unit,将其视为 an int,可能需要 4 个字节。让代码(测试用例)说实话:
\n(需要Java 9+,由于String\的方法codePoints()和chars())
@Test\npublic void test() {\n String s = "Hi, \xe4\xbd\xa0\xe5\xa5\xbd, \xe3\x81\x8a\xe3\x81\xaf\xe3\x82\x88\xe3\x81\x86, \xce\xb1-\xce\xa9\\uD834\\uDD1E"; // last real character is "", that takes 2 code unit,\n assertEquals(s.length(), s.toCharArray().length); // length() is based on char (aka code unit), not code point,\n\n System.out.printf("input string:\\t\\"%s\\"%n%n", s);\n\n System.out.println("------ as code point (aka. real character) ------");\n // code point,\n s.codePoints().forEach(cp -> System.out.println(Character.toChars(cp)));\n assertEquals(s.codePoints().count(), s.length() - 1); // last read character takes 2 unit code,\n assertEquals(s.codePoints().count(), s.codePointCount(0, s.length())); // there is a method codePointCount() on String to get code point count on given char range,\n\n System.out.println("\\n------ as char (aka. code unit) ------");\n // chars (aka. code unit),\n s.chars().forEach(c -> System.out.println(Character.toChars(c)));\n assertEquals(s.chars().count(), s.length()); // string length is the count of code unit, not code point,\n}\nRun Code Online (Sandbox Code Playgroud)\n输出:
\n\n输入字符串:“嗨,\xe4\xbd\xa0\xe5\xa5\xbd,\xe3\x81\x8a\xe3\x81\xaf\xe3\x82\x88\xe3\x81\x86,\xce\xb1- \xce\xa9"\n\n------ 作为代码点(又称真实字符)------\nH\ni\n,\n \n\xe4\xbd\xa0\n\ xe5\xa5\xbd\n,\n\n\xe3\x81\x8a\n\xe3\x81\xaf\n\xe3\x82\x88\n\xe3\x81\x86\n,\n\n\ xce\xb1\n-\n\xce\xa9\n\n\n-------- 作为 char (又名代码单元) ------\nH\ni\n,\n \n\ xe4\xbd\xa0\n\xe5\xa5\xbd\n,\n\n\xe3\x81\x8a\n\xe3\x81\xaf\n\xe3\x82\x88\n\xe3\x81\x86 \n,\n\n\xce\xb1\n-\n\xce\xa9\n?\n?\n\n
最后一个真实字符是,它需要 2 个代码单元\\uD834\\uDD1E,并且是单个的code point,当尝试分别打印 2 个代码单元时,它们无法被识别,并且分别显示?。
| 归档时间: |
|
| 查看次数: |
13473 次 |
| 最近记录: |