A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

田明老师

初级黑马

  • 黑马币:24

  • 帖子:7

  • 精华:0

© 田明老师 初级黑马   /  2016-5-25 16:28  /  4036 人查看  /  63 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 田明老师 于 2016-5-25 16:34 编辑

            Hello, 大家好, 在日常的学习中, 同学们对于 char 总是会感到有点陌生和奇怪.大家的"不良反应"其实是正常的, 因为首先大家才刚刚接触 Java, 还没有进入到学习状态, 其次 char 类型在开发中使用的也没有那么频繁. 但是作为一个优秀的开发人员, 还是要把知识掌握得更全面些才好, 所以呢, 今天我们来聊聊 char.

char的使用:

  • char 表示单个字符
  1. char c1 = 'a';
  2. System.out.println("c1="+c1);
复制代码
在 C 语言中, 单个 char 是无法表示汉字的. 这里大家可能会好奇, 那么 在 Java 语言中的 char 可不可以表示单个汉字呢? 答案是肯定的.  因为 char 类型数据是 Unicode 编码的, 占两个字节, 而 中文也是占两个字节.
  • char 表示单个汉字

  1. char c2= '帅';
  2. System.out.println("c2="+c2);
复制代码
  • char 的取值范围
下面我们再来看这个程序
  1. char c3 = 97;
  2. System.out.println("c3="+c3);
复制代码
猜猜看, 这个会输出什么???
是不是大吃一惊, 竟然输出了 a !!! 顿时晕菜有没有!!!!!!
我们先来想想 byte:
  1. byte b = 100;
复制代码
这个是没有问题的. 仔细想想为什么没有问题? 因为 byte 的取值范围在 -128 ~ 127 之间. Java编译器有常量优化机制, 可以直接判断值, 因此编译器在编译的时候, 发现 100 在 byte 的取值范围之内, 可以赋值成功. 那么为什么把 97 赋值给 char 也是没有问题的呢? 那是因为 char 类型的取值范围是在 0 ~ 65535 之间, 所以可以赋值成功. 好, 这个大家理解了, 那么问题又来了, 为什么 c3 会输出 a 呢 ? 这是因为对于 char 类型数据, 有一张专门的字符代码表用来进行 一 一 对照的关系.  其实 char 还可以表示很多符号, 比如扑克牌的红桃, 梅花, 方块, 黑桃, 比如一些希腊字母, ....... 感兴趣的同学可以自己尝试.
  • char 参与运算
  1. int i = 'a' + 1;
  2. System.out.println("i="+i);
复制代码
这个会输出什么呢? 答案是 i = 98. 因为通过上面的练习我们知道了 char 的取值范围是小于 int 类型的, 因此在 'a' + 1 这个操作中, char 类型被提升到 int 类型, 这叫做隐式转换, 也叫做自动类型提升. 通过查表, 我们看到 'a' 对应的值是 97, 所以这里应该输出的是 98. 再来看下面这个例子,
  1. char c4 = (char)('a'+1);
  2. System.out.println("c4="+c4);
复制代码
这个会输出什么呢? 答案是 b. 在上面的例子中我们知道了 'a'+1会生成一个 int 类型的值, 而这里等号的左边我们使用 char 类型去接收, 因此需要进行强制类型转换, 将 int 值强转成 char, 通过查表我们看到 98 对应的 char 类型数据是 b.
到了这里, 关于 char 的使用基本就讲完了, 其实并没有那么难以理解吧!
有些同学心里还是会有疑惑, 为什么要转来转去的这么麻烦. 其实 Java 语言在设计的时候, 是为了做到最大的兼容性.

char 的设计思想


          char 类型用于表示 Unicode 编码的字符单元, 通常用来表示字符常量. 例如, ‘A’是编码为65所对于的字符常量. 它与A”不同, “A”是一个包含字符A的字符串.  Unicode编码单元可以表示为十六进制值, 其范围从 \u0000 到 \Uffff.
        要想弄清 char 类型, 就必须了解 Unicode 编码表. Unicode 打破了传统字符编码方法的限制. 在Unicode出现之前, 已经有许多种不同的标准.: 比如美国的 ASCII, 西欧语言的 ISO 8859-1, 中国的 GB 18030等. 这样就产生了两个问题, 一个是对于任意给定的代码值, 在不同的编码方案下有可能对应不同的字母; 二是其编码长度可能不同, 因为有些字符采用的是单字节编码, 而另外一些字符则需要两个或更多个字节.
       设计Unicode编码的目的就是要解决这些问题. 在20世纪80年代开始启动设计工作时, 人们认为两个字节的代码宽度足以能够对世界上各种语言的所有字符进行编码, 并有足够的空间留给未来的扩展. 在1991年发布了 Unicode 1.0, 当时仅占用 65536 个代码值中不到一半的部分. 在设计 Java 时决定采用16位的 Unicode 字符集, 这样会比使用8位字符集的程序设计语言 (C/C++) 有很大改进. 但是经过一段时间, 在增加了大量汉语, 日语和韩语的文字后, Unicode字符超过了65536个, 现在, 16位的char类型已经不能满足描述所有Unicode字符的需要了.
       那么, Java该如何解决这个问题呢???
       首先要介绍一个代码点(code point)的概念. 代码点是指与一个编码表中的某个字符对应的代码值. 在Unicode标准中, 代码点采用十六进制书写, 并加上前缀U+, 例如U+0041就是字母A的代码点. Unicode的代码点可以分成17个代码级别(code plane). 第一个代码级别称为基本的多语言级别(basic multilingual plane), 代码点从U+0000到U+FFFF, 其中包括了经典的Unicode代码, 其余的16个附加级别, 代码点从U+10000到U+10FFFF, 其中包括了一些辅助字符(supplementarycharacter).
       UTF-16 编码采用不同长度的编码代表所有Unicode代码点. 在基本的多语言级别中, 每个字符用16位表示, 通常被称为代码单元(codeunit); 而辅助字符采用一对连续的代码单元进行编码. 这样构成的编码值一定落入基本的多语言级别中空闲的2048字节内, 通常被称为替代区域. 这样设计十分巧妙, 我们可以从中迅速地知道一个代码单元是一个字符的的编码, 还是一个辅助字符的第一或第二部分.
       在Java中, char类型用UTF-16编码描述Unicode代码点的代码单元. 我们强烈建议不要在程序中使用char类型,  最好将需要处理的字符串用抽象数据类表示.

总结

可能大家对于 char 的设计思想不太明白, 实际上在真实的项目开发中, 我们也极少会使用到 char 进行运算, 而如果不是专门从事编解码等程序底层工作的人, 也很少有机会去研究这些. 因此大家只要知道 char 是什么, 以及如何使用 char 进行运算, 并且知道 char 是采用 Unicode 编码, 占两个字节, 可以用来表示中文这些基本概念就足够啦!
好了,关于 char 就给大家分享到这里~   咱们黑马见哈~





63 个回复

倒序浏览
干货
回复 使用道具 举报
学过了,过来复习一下!!!顺便支持一下
回复 使用道具 举报
这些都是好东西
回复 使用道具 举报
这些细致的东西,忍不住给你点赞
回复 使用道具 举报
谢谢啦, 刚宿舍在讨论这个问题马上就看到了
回复 使用道具 举报
点赞。。。。好贴。。。。。
回复 使用道具 举报
楼主心太细了
回复 使用道具 举报
活到老学到老
回复 使用道具 举报
恩,给力,填明了我心中的空白{:3_62:}
回复 使用道具 举报
签个到,呦西,司格义
回复 使用道具 举报
Lsc01 中级黑马 2016-5-26 18:23:57
12#
这些都是好东西,基础但实用
回复 使用道具 举报
基础是关建的么?朋友做了一年安卓都忘玩了.
回复 使用道具 举报
大家好呀、越来越热了
回复 使用道具 举报
总结很好啊
回复 使用道具 举报
loop 中级黑马 2016-5-26 20:04:32
16#
忍不住,点个赞
回复 使用道具 举报
赞赞赞赞
回复 使用道具 举报
学过了,过来复习一下!!!顺便支持一下
回复 使用道具 举报
学到了,楼主写的真好,大爱!
回复 使用道具 举报
楼主写的和详细清晰
回复 使用道具 举报
1234下一页
您需要登录后才可以回帖 登录 | 加入黑马