为什么Java中的字符占用的空间是C中字符的两倍?
在Java中,字符是16位,C是8位。
更普遍的问题是为什么会这样?
找出为什么你需要查看历史并就此主题得出结论/意见。
当C在美国开发时,ASCII在那里非常标准,你只需要7位,但是有8位你也可以处理一些非ASCII字符。看起来绰绰有余。许多基于文本的协议(如SMTP(电子邮件),XML和FIX)仍然只使用ASCII字符。电子邮件和XML编码非ASCII字符。二进制文件,套接字和流仍然只是8位字节本机。
顺便说一句:C可以支持更广泛的字符,但这不是简单的char
当Java开发时,16位似乎足以支持大多数语言。从那时起,unicode已扩展到65535以上的字符,Java必须添加对UTF-16字符的代码点的支持,并且可以是一个或两个16位字符。
因此,将byte
设为一个字节,char
为无符号16位值,这在当时是有意义的。
顺便说一句:如果您的JVM支持-XX:+UseCompressedStrings
,它可以使用字节而不是字符串仅用于8位字符的字符串。
由于Java使用Unicode,因此C通常默认使用ASCII。
有各种各样的Unicode编码,但Java使用UTF-16,每个字符使用一个或两个16位代码单元。 ASCII始终使用每个字符一个字节。
Java 2平台在char数组和String和StringBuffer类中使用UTF-16表示。
Java是一种现代语言,它出现在早期的Unicode时代(90年代初),所以它默认支持Unicode,就像今天的许多新语言(如C#)一样。当Java和许多新框架(如Qt)被设计时,Unicode是在UCS-2中编码的固定16位类型,因此它们对于字符使用16位值是有意义的
当然后来Unicode Consortium意识到16位是不够的,所以他们将Unicode代码点范围扩展到21位,并将UCS-2更改为UTF-16,以避免破坏假设16位Unicode的代码。因此,使用16位字符的旧实现被卡住了
相比之下,C是一种“古老”语言,它是在Java之前几十年发明的,当时Unicode远非一件事。这是7位ASCII的年龄,因此C使用8位char1,因为它足以使char
变量包含所有ASCII值。当进入Unicode时,为了避免破坏旧代码,他们决定使用不同的字符类型wchar_t
。这意味着char
继续具有旧的大小,就像在Java中一样
谈到wchar_t
,它是如此不可移植,以至于C和C ++标准都需要在2011年版本中引入新的字符类型char16_t
and char32_t
后来我们看到了UTF-8的出现,它被证明优于UTF-16,因为它独立于字节序,通常占用更少的空间,最重要的是它不需要改变标准的C字符串函数。接收char*
的大多数用户函数将继续工作,无需特殊的Unicode支持
1严格来说,C中的char
只需要至少有8位。见What platforms have something other than 8-bit char?
Java char是UTF-16编码的unicode代码点,而C在大多数情况下使用ascii编码。