• 深入理解JAVA中char的本质
  • 顺风顺水 发表于 2017/2/23 10:17:00 | 分类标签: JAVA乱码 编码格式
  •  char的本质

    Java内部进行字符处理时,采用的都是Unicode,具体编码格式是UTF-16BE。简单回顾一下,UTF-16使用两个或四个字节表示一个字 符,Unicode编号范围在65536以内的占两个字节,超出范围的占四个字节,BE (Big Endian)就是先输出高位字节,再输出低位字节,这与整数的内存表示是一致的。

    char本质上是一个固定占用两个字节的无符号正整数,这个正整数对应于Unicode编号,用于表示那个Unicode编号对应的字符。

    由于固定占用两个字节,char只能表示Unicode编号在65536以内的字符,而不能表示超出范围的字符。

    那超出范围的字符怎么表示呢?使用两个char。类String有一些相关的方法,后续文章介绍。

    在这个认识的基础上,我们再来看下char的一些行为,就比较容易理解了。

    char的赋值

    char有多种赋值方式:

    1. char c = 'A'
    2. char c = '马'
    3. char c = 39532
    4. char c = 0x9a6c
    5. char c = '\u9a6c'

    第1种赋值方式是最常见的,将一个能用Ascii码表示的字符赋给一个字符变量。

    第 2种也很常见,但这里是个中文字符,需要注意的是,直接写字符常量的时候应该注意文件的编码,比如说,GBK编码的代码文件按UTF-8打开,字符会变成乱码,赋值的时候是按当前的编码解读方式,将这个字符形式对应的Unicode编号值赋给变量,'马'对应的Unicode编号是39532,所以第2种赋值和第3种是一样的。

    第3种是直接将十进制的常量赋给字符,第4种是将16进制常量赋给字符,第5种是按Unicode字符形式。

    以上,2,3,4,5都是一样的,本质都是将Unicode编号39532赋给了字符。

    char的运算

    由于char本质上是一个整数,所以可以进行整数可以进行的一些运算,在进行运算时会被看做int,但由于char占两个字节,运算结果不能直接赋值给char类型,需要进行强制类型转换,这和byte, short参与整数运算是类似的。

    char类型的比较就是其Unicode编号的比较。

    char 的加减运算就是按其Unicode编号进行运算,一般对字符做加减运算没什么意义,但Ascii码字符是有意义的。比如大小写转换,大写A-Z的编号是 65-90,小写a-z的编号是97-122,正好相差32,所以大写转小写只需加32,而小写转大写只需减32。加减运算的另一个应用是加密和解密,将 字符进行某种可逆的数学运算可以做加解密。

    char的位运算可以看做就是对应整数的位运算,只是它是无符号数,也就是说,有符号右移>>和无符号右移>>>的结果是一样的。 

    char的二进制

    既然char本质上是整数,查看char的二进制表示,同样可以用Integer的方法,如下所示:

    char c = '马';
    System.out.println(Integer.toBinaryString(c));

    输出为 1001101001101100

    小结

    本节介绍了char的本质,它固定占用两个字节,实际上是一个整数,表示字符的Unicode编号,不在65536编号内的字符一个char表示不了,需要用两个char。

  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:顺风顺水
  • 加入时间:2013/7/16 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮