黑马程序员技术交流社区

标题: 关于char, 你应该知道的一切 [打印本页]

作者: 田明老师    时间: 2016-5-25 16:28
标题: 关于char, 你应该知道的一切
本帖最后由 田明老师 于 2016-5-25 16:34 编辑

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

char的使用:

  1. char c1 = 'a';
  2. System.out.println("c1="+c1);
复制代码
在 C 语言中, 单个 char 是无法表示汉字的. 这里大家可能会好奇, 那么 在 Java 语言中的 char 可不可以表示单个汉字呢? 答案是肯定的.  因为 char 类型数据是 Unicode 编码的, 占两个字节, 而 中文也是占两个字节.
  1. char c2= '帅';
  2. System.out.println("c2="+c2);
复制代码
下面我们再来看这个程序
  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 还可以表示很多符号, 比如扑克牌的红桃, 梅花, 方块, 黑桃, 比如一些希腊字母, ....... 感兴趣的同学可以自己尝试.
  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 就给大家分享到这里~   咱们黑马见哈~






作者: xushengbin    时间: 2016-5-25 16:52
干货
作者: ylw787442926    时间: 2016-5-25 17:03
学过了,过来复习一下!!!顺便支持一下
作者: daniel031699    时间: 2016-5-25 17:09
这些都是好东西
作者: wangzifei    时间: 2016-5-25 17:51
这些细致的东西,忍不住给你点赞
作者: 18634319112    时间: 2016-5-25 19:36
谢谢啦, 刚宿舍在讨论这个问题马上就看到了
作者: 我有上将潘凤    时间: 2016-5-25 23:35
点赞。。。。好贴。。。。。
作者: 一架飞机CE3    时间: 2016-5-25 23:45
楼主心太细了
作者: gsa798780633    时间: 2016-5-26 15:35
活到老学到老
作者: 杨文君老师    时间: 2016-5-26 16:22
恩,给力,填明了我心中的空白{:3_62:}
作者: w125621538    时间: 2016-5-26 18:08
签个到,呦西,司格义
作者: Lsc01    时间: 2016-5-26 18:23
这些都是好东西,基础但实用
作者: jialp1024    时间: 2016-5-26 18:29
基础是关建的么?朋友做了一年安卓都忘玩了.
作者: yourlike    时间: 2016-5-26 18:29
大家好呀、越来越热了
作者: TomZhou    时间: 2016-5-26 19:28
总结很好啊
作者: loop    时间: 2016-5-26 20:04
忍不住,点个赞
作者: 酱油    时间: 2016-5-26 20:45
赞赞赞赞
作者: 罗勇    时间: 2016-5-26 21:28
学过了,过来复习一下!!!顺便支持一下
作者: ygxheima    时间: 2016-5-26 21:31
学到了,楼主写的真好,大爱!
作者: cofujun    时间: 2016-5-26 21:41
楼主写的和详细清晰
作者: hjbing456    时间: 2016-5-26 22:03
char 很强大。
作者: yourlike    时间: 2016-5-26 22:04
一天只能得到一个技术分吗
作者: woshijingke    时间: 2016-5-26 22:05
一天只能得到一个技术分吗
作者: cofujun    时间: 2016-5-26 22:06
说的很好
作者: ylw787442926    时间: 2016-5-26 22:09
看完之后才知道,本来以为很简单的char也有这摩多花样,学习到了
作者: 大笑哈哈    时间: 2016-5-26 22:12
长知识了,char直接赋值居然打印的是字母
作者: 我类个去    时间: 2016-5-26 22:20
厉害啊,越学感觉要学的越多啊
作者: 虾米1995丶    时间: 2016-5-26 22:26
char很强大!
作者: laputa    时间: 2016-5-26 22:27
不错的东西,学无止境
作者: JohnChan    时间: 2016-5-26 22:28
膜拜大虾,过来签个到
作者: 漆黑明月光    时间: 2016-5-26 22:30
露个脸...膜拜
作者: static小白    时间: 2016-5-26 22:32
我想我真的需要
作者: 我是你岁哥❤环    时间: 2016-5-26 22:34
char 是采用 Unicode 编码, 占两个字节, 可以用来表示中文这些基本概念
作者: zhglyxgs    时间: 2016-5-26 22:34
值得收藏!
作者: chexinxin    时间: 2016-5-26 22:55
2016年5月26日 星期四
今天去十渡活动,进行了漂流,竹筏,和登山玩的比想象的要好。
作者: ︶夜戏乀梦红尘    时间: 2016-5-26 22:59
学习学习,大赞
作者: 清风幕竹    时间: 2016-5-26 23:10
顶顶顶,加油加油
作者: wy123580    时间: 2016-5-26 23:48
顶起顶起顶起
作者: frank5    时间: 2016-5-26 23:55
楼主威武!!!!
作者: 追风筝的少年    时间: 2016-5-26 23:56
世界上最真情的相依就是你在try我在catch,无论你发神马脾气,我都静静接受,默默处理!
作者: yiyajing    时间: 2016-5-27 00:03
顶,楼主真棒,有用,见识了
作者: yuanqingleivip    时间: 2016-5-27 00:07
来学习了,老师辛苦了!
作者: nanliner    时间: 2016-5-27 00:08
说的对,说的好,说的棒
作者: wei19910428    时间: 2016-5-27 00:21
好好,感谢楼主的分享
作者: woshijingke    时间: 2016-5-27 00:21
好好,感谢楼主的分享
作者: A昌_e244R    时间: 2016-5-27 00:21
好好学习,天天向上
作者: xiangmintian    时间: 2016-5-27 00:28
char  CHAR好麻烦的东西
作者: jeremyl    时间: 2016-5-27 00:30
感谢明哥分享
作者: 我love    时间: 2016-5-27 00:40
点赞,好好学习
作者: xiangmintian    时间: 2016-5-27 00:41
char是基本数据类型,占两个字节,我觉得不要想复杂,其实它和数值可以相互转化,有相应的编码规定,它能并只能表示一个单元素,编程会用到的把,比如性别,为了统一规范,就要一个字,男或者女,省的写男生,男人,男孩,什什么的
作者: xiangmintian    时间: 2016-5-27 00:42
去哪签啊 啊啊a

作者: w125621538    时间: 2016-5-27 00:46
现在签个到,祈祷这次点招能顺利通过
作者: SkyBlack    时间: 2016-5-27 08:40
编解码底层工作的人。。。。。。
作者: innovator    时间: 2016-5-27 21:00
学到了,学习要知其然,知其所以然...
作者: 苏新伟    时间: 2016-6-18 22:48
明哥V5,说得很详细,赞赞赞
作者: 懂得珍惜    时间: 2016-6-19 13:36
老师写的很不错
作者: 张作辉    时间: 2016-6-19 21:27
我来了

作者: zhoubinjian    时间: 2016-6-19 21:38
好东西,,,谢谢分享
作者: jeremyhe    时间: 2016-6-20 00:19
代码点是个什么东东? 还是有点懵逼的感觉啊
作者: yuanqing    时间: 2016-6-23 21:28
支持田明老师
作者: AndyYan    时间: 2016-6-23 21:33
mark,谢谢。
作者: 黑马的黑马    时间: 2016-6-23 21:45
学到了,赞一个

作者: 940752944    时间: 2016-6-23 22:11
讲解的很仔细,解决了对char的问题的一些困惑
作者: Ake丶    时间: 2016-6-23 23:30
可以哦,受教了!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2