美文网首页
Java中的char为什么占两个字节?能表示所有的字符吗?

Java中的char为什么占两个字节?能表示所有的字符吗?

作者: 卡路fly | 来源:发表于2020-05-30 12:27 被阅读0次

    之所以是两个字节,是因为Java内部使用UTF-16编码,所以char为了表示BMP中的字符,所以占了两个字节。很明显,不能表示所有字符。

    Unicode是一种字符集规范,而且还在不断发展之中。我们常说的UTF-8,UTF-16编码是其不同的两种实现。请注意,字符集和编码不是一回事。Unicode规范好比就是定义了每个字符对应一个数字,至于如何把这个数字存放在计算机中,那是另一回事。Unicode收录的每个字符对应一个数字,称作码点(code point),通常用“U+”后面跟着一个十六进制数表示。

    其实UTF-16比UTF-8更早出现,在UTF-16之前还存在UCS-2,该编码固定使用16位编码,后来发现16位根本不够使用,IEEE曾推荐过UCS-4,即固定使用4个字节编码,但因为太过浪费空间被Unicode拒绝采纳了。此时,UTF-16就出现了。Unicode将16位的字符集做了延申,并规定每216为一个plane, 第一个plane称作 Basic Multilingual Plane(简称 BMP), 这里面的字符使用两个字节。对于超出了第一个plane的其他字符,将被收录在其他层级的plane,并使用第一层的代理(surrogate)将其表示,占用四个字节。至于怎么表示以及怎么编码解码的,请移步维基百科,有详细的解释。

    JVM内部使用的是UTF-16编码。不管代码文件中char使用的是什么编码,都将被JVM转化为UTF-16而且只用两个字节,也就是说Java中的char占用两个字节,只能表示Unicode中第一层(BMP)中的字符,对于其他字符会报错:Invalid Character Constant, 而String中是可以的。


    • ASCII 码
      学过计算机的人都知道 ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126 是打印字符,可以通过键盘输入并且能够显示出来。

    • ISO-8859-1
      128 个字符显然是不够用的,于是 ISO 组织在 ASCII 码基础上又制定了一些列标准用来扩展 ASCII 编码,它们是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵盖了大多数西欧语言字符,所有应用的最广泛。ISO-8859-1 仍然是单字节编码,它总共能表示 256 个字符。

    • GB2312
      它的全称是《信息交换用汉字编码字符集 基本集》,它是双字节编码,总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,包含 6763 个汉字。

    • GBK
      全称叫《汉字内码扩展规范》,是国家技术监督局为 windows95 所制定的新的汉字内码规范,它的出现是为了扩展 GB2312,加入更多的汉字,它的编码范围是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能表示 21003 个汉字,它的编码是和 GB2312 兼容的,也就是说用 GB2312 编码的汉字可以用 GBK 来解码,并且不会有乱码。

    • GB18030
      全称是《信息交换用汉字编码字符集》,是我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与 GB2312 编码兼容,这个虽然是国家标准,但是实际应用系统中使用的并不广泛。

    • UTF-16
      说到 UTF 必须要提到 Unicode(Universal Code 统一码),ISO 试图想创建一个全新的超语言字典,世界上所有的语言都可以通过这本字典来相互翻译。可想而知这个字典是多么的复杂,关于 Unicode 的详细规范可以参考相应文档。Unicode 是 Java 和 XML 的基础,下面详细介绍 Unicode 在计算机中的存储形式。

    UTF-16 具体定义了 Unicode 字符在计算机中存取方法。UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示,两个字节是 16 个 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以 UTF-16 作为内存的字符存储格式的一个很重要的原因。

    • UTF-8
      UTF-16 统一采用两个字节表示一个字符,虽然在表示上非常简单方便,但是也有其缺点,有很大一部分字符用一个字节就可以表示的现在要两个字节表示,存储空间放大了一倍,在现在的网络带宽还非常有限的今天,这样会增大网络传输的流量,而且也没必要。而 UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以是由 1~6 个字节组成。

    UTF-8 有以下编码规则:

    如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)。可见,所有 ASCII 编码已经是 UTF-8 了。
    如果一个字节,以 11 开头,连续的 1 的个数暗示这个字符的字节数,例如:110xxxxx 代表它是双字节 UTF-8 字符的首字节。
    如果一个字节,以 10 开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节

    ————————————————
    版权声明:本文为CSDN博主「harrisonlee.net」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/LZCDTU/article/details/103865748

    相关文章

      网友评论

          本文标题:Java中的char为什么占两个字节?能表示所有的字符吗?

          本文链接:https://www.haomeiwen.com/subject/shvczhtx.html