为什么 Java char 使用 UTF-16?

2022-09-01 15:59:13

最近,我阅读了很多关于Unicode码位的东西,以及它们如何随着时间的推移而演变,当然我也读过 http://www.joelonsoftware.com/articles/Unicode.html

但是我找不到真正的原因是为什么Java使用UTF-16作为字符。

例如,如果我的字符串包含 1024 个 ASCII 作用域字符串的字母。这意味着它等于2KB字符串内存,它将以任何方式消耗。1024 * 2 bytes

因此,如果Java基本字符是UTF-8,则只有1KB的数据。即使字符串中有任何字符需要2字节,例如10个字符的“字”,自然也会增加内存消耗的大小。(1014 * 1 byte) + (10 * 2 bytes) = 1KB + 20 bytes

结果不是那么明显,我没有说ASCII,但我对此的好奇心是为什么它不是UTF-8,它也只是照顾多字节字符。UTF-16 在任何包含大量非多字节字符的字符串中看起来都像是浪费内存。1KB + 20 bytes VS. 2KB

这背后有什么好的理由吗?


答案 1

Java在2004/2005年过渡到UTF-16之前使用了UCS-2。最初选择UCS-2的原因主要是历史

Unicode 最初被设计为固定宽度的 16 位字符编码。Java 编程语言中的基元数据类型 char 旨在通过提供可以保存任何字符的简单数据类型来利用此设计。

这一点,以及 UTF-16 的诞生,在 Unicode FAQ 页面得到了进一步的解释:

最初,Unicode被设计为纯16位编码,旨在表示所有现代脚本。(古代文字将用私人使用的字符表示。随着时间的流逝,特别是在添加了超过 14,500 个复合字符以与旧版集兼容之后,很明显,16 位对于用户社区来说是不够的。由此产生了UTF-16。

正如@wero已经提到的,使用 UTF-8 无法高效地完成随机访问。因此,所有事情都权衡了,UCS-2似乎是当时的最佳选择,特别是因为该阶段没有分配任何补充字符。这使得UTF-16成为除此之外最容易的自然进展。


答案 2

其中一个原因是随机访问或迭代 String 字符的性能特征:

UTF-8 编码使用可变数字 (1-4) 字节对 Unicode 字符进行编码。因此,按索引:访问字符的实现方式将比 使用的数组访问更复杂,并且速度更慢。String.charAt(i)java.lang.String


推荐