为什么 Java char 使用 UTF-16?

Why Java char uses UTF-16?

最近我读了很多关于 Unicode 代码点以及它们如何随着时间演变的东西,我当然也读了 http://www.joelonsoftware.com/articles/Unicode.html 这个。

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

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

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

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

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

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

UTF-8 编码使用可变数量 (1-4) 字节来编码 unicode 字符。因此,通过索引访问字符:String.charAt(i)java.lang.String.

使用的数组访问实现起来更复杂,速度也更慢。

Java 使用 UCS-2 before transitioning over UTF-16 in 2004/2005. The reason for the original choice of UCS-2 is mainly historical:

Unicode was originally designed as a fixed-width 16-bit character encoding. The primitive data type char in the Java programming language was intended to take advantage of this design by providing a simple data type that could hold any character.

这和UTF-16的诞生更进一步explained by the Unicode FAQ page:

Originally, Unicode was designed as a pure 16-bit encoding, aimed at representing all modern scripts. (Ancient scripts were to be represented with private-use characters.) Over time, and especially after the addition of over 14,500 composite characters for compatibility with legacy sets, it became clear that 16-bits were not sufficient for the user community. Out of this arose UTF-16.

由于@wero already mentioned,使用 UTF-8 无法有效地进行随机访问。所以权衡利弊,UCS-2 似乎是当时最好的选择,尤其是在那个阶段还没有分配增补角色的情况下。这使得 UTF-16 成为最简单的自然进程。