本系列文章经补充和完善,已修订整理成书《Java编程的逻辑》,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接http://item.jd.com/12299018.html


看似简单的char

通过前两节,我们应该对字符和文本的编码和乱码有了一个清晰的认识,但前两节都是与编程语言无关的,我们还是不知道怎么在程序中处理字符和文本。

本节讨论在Java中进行字符处理的基础 - char,Java中还有Character, String, StringBuffer, StringBuilder等类进行文本处理,他们的基础都是char,我们在后续文章中介绍这些类。

char看上去是很简单的,正如我们在第2节所说,char用于表示一个字符,这个字符可以是中文字符,也可以是英文字符。赋值时把常量字符用单引号括起来,例如:

char c = 'A';
char z = '中';

但我们在第3节抛出了一个问题,为什么字符类型也可以进行算术运算和比较?char的本质到底是什么呢?

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。

我们回顾一下以前所有的章节,整理一下思路。

我们说,所谓程序,主要就是告诉计算机要对什么数据做什么操作。第1节我们介绍了如何通过变量定义数据,第2节介绍了数据的第一个操作 - 赋值,第3节介绍了数据的基本运算,第4节到本节介绍了数据的二进制表示及位运算。

至此,我们可以定义基本数据类型,以及对基本数据进行基本运算了,但实际操作中不是只有运算本身的,我们需要有表达类似"如果"/"那么"逻辑的机制,即根据具体情况选择执行的机制,也就是流程控制。

----------------

未完待续,查看最新文章,敬请关注微信公众号“老马说编程”(扫描下方二维码),深入浅出,老马和你一起探索Java编程及计算机技术的本质。原创文章,保留所有版权。

-----------

更多相关原创文章

计算机程序的思维逻辑 (1) - 数据和变量

计算机程序的思维逻辑 (2) - 赋值

计算机程序的思维逻辑 (3) - 基本运算

计算机程序的思维逻辑 (4) - 整数的二进制表示与位运算

计算机程序的思维逻辑 (5) - 小数计算为什么会出错?

计算机程序的思维逻辑 (6) - 如何从乱码中恢复 (上)?

计算机程序的思维逻辑 (7) - 如何从乱码中恢复 (下)?

计算机程序的思维逻辑 (8) - char的真正含义的更多相关文章

  1. 【转载】计算机程序的思维逻辑 (8) - char的真正含义

    看似简单的char 通过前两节,我们应该对字符和文本的编码和乱码有了一个清晰的认识,但前两节都是与编程语言无关的,我们还是不知道怎么在程序中处理字符和文本. 本节讨论在Java中进行字符处理的基础 - ...

  2. 计算机程序的思维逻辑 (29) - 剖析String

    上节介绍了单个字符的封装类Character,本节介绍字符串类.字符串操作大概是计算机程序中最常见的操作了,Java中表示字符串的类是String,本节就来详细介绍String. 字符串的基本使用是比 ...

  3. 计算机程序的思维逻辑 (64) - 常见文件类型处理: 属性文件/CSV/EXCEL/HTML/压缩文件

    对于处理文件,我们介绍了流的方式,57节介绍了字节流,58节介绍了字符流,同时,也介绍了比较底层的操作文件的方式,60节介绍了随机读写文件,61节介绍了内存映射文件,我们也介绍了对象的序列化/反序列化 ...

  4. Java编程的逻辑 (8) - char的真正含义

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  5. 计算机程序的思维逻辑 (31) - 剖析Arrays

    数组是存储多个同类型元素的基本数据结构,数组中的元素在内存连续存放,可以通过数组下标直接定位任意元素,相比我们在后续章节介绍的其他容器,效率非常高. 数组操作是计算机程序中的常见基本操作,Java中有 ...

  6. 计算机程序的思维逻辑 (30) - 剖析StringBuilder

    上节介绍了String,提到如果字符串修改操作比较频繁,应该采用StringBuilder和StringBuffer类,这两个类的方法基本是完全一样的,它们的实现代码也几乎一样,唯一的不同就在于,St ...

  7. 计算机程序的思维逻辑 (70) - 原子变量和CAS

    从本节开始,我们探讨Java并发工具包java.util.concurrent中的内容,本节先介绍最基本的原子变量及其背后的原理和思维. 原子变量 什么是原子变量?为什么需要它们呢? 在理解synch ...

  8. 计算机程序的思维逻辑 (73) - 并发容器 - 写时拷贝的List和Set

    本节以及接下来的几节,我们探讨Java并发包中的容器类.本节先介绍两个简单的类CopyOnWriteArrayList和CopyOnWriteArraySet,讨论它们的用法和实现原理.它们的用法比较 ...

  9. 计算机程序的思维逻辑 (33) - Joda-Time

    Joda-Time上节介绍了JDK API中的日期和时间类,我们提到了JDK API的一些不足,并提到,实践中有一个广泛使用的日期和时间类库,Joda-Time,本节我们就来介绍Joda-Time.俗 ...

随机推荐

  1. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  2. 设置tomcat远程debug

    查看端口占用情况命令: netstat -tunlp |grep 8000 tomcat 启动远程debug: startup.sh 中的最后一行 exec "$PRGDIR"/& ...

  3. Unity3D框架插件uFrame实践记录(二)

    5.创建属性和命令 本小节主要内容包括: 在Element节点上创建属性数据 在Element节点上创建命令数据 5.1.在Element节点上创建属性数据 在这里,我们首先为Login节点中的属性( ...

  4. iOS架构一个中型普通App的一些经验总结

    这一版比较完善的的App终于提交审核了.有时间写写自己的一些经验的总结了.自己主导的从0到比较成型的app到目前来说也只有两个,但是其中的很多东西都是大同小异.基本上是想到了什么就写什么,感觉写的不到 ...

  5. equals变量在前面或者在后面有什么区别吗?这是一个坑点

    我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...

  6. 2016/12/28_javascript

    今天学习的主要内容: javascript: 1.if语句,switch语句,while循环以及for循环: 1)if语句 if(boolean){}; if(boolean){} else if(b ...

  7. 【干货分享】流程DEMO-付款申请单

    流程名: 付款申请单  业务描述: 包括每月固定开支.固定资产付款.办公用品付款.工资发放.个人所得税缴纳.营业税缴纳.公积金.社保缴纳和已签订合同的按期付款,最后是出纳付款,出纳核对发票. 流程发起 ...

  8. 【从零开始学BPM,Day4】业务集成

    [课程主题] 主题:5天,一起从零开始学习BPM [课程形式] 1.为期5天的短任务学习 2.每天观看一个视频,视频学习时间自由安排. [第四天课程] 1.课程概要 Step 1 软件下载:H3 BP ...

  9. 仿陌陌的ios客户端+服务端源码项目

    软件功能:模仿陌陌客户端,功能很相似,注册.登陆.上传照片.浏览照片.浏览查找附近会员.关注.取消关注.聊天.语音和文字聊天,还有拼车和搭车的功能,支持微博分享和查找好友. 后台是php+mysql, ...

  10. Spark Streaming+Kafka

    Spark Streaming+Kafka 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端, ...