char类型

char是2个字节,和short一样。

char用单引号来表示。

char可以通过数字来表示,也可以通过字母来表示,也可以通过unicode编码单元来表示,特殊字符还可以通过\+字符来表示。如下:

  1. package com.zjf;
  2.  
  3. public class Test {
  4.  
  5.    public static void main(String[] args) {
  6.  
  7.       char c1 = 'A';
  8.       System.out.println(c1);
  9.       char c2 = 65;
  10.       System.out.println(c2);
  11.       char c3 = '\u0041';
  12.       System.out.println(c3);
  13.       char c4 = '\n';
  14.       System.out.println(c4);
  15.    }
  16. }

输出:

unicode编码

要想理解java 的char类型,必须要先了解unicode编码:

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000 至 0xFFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个。然而目前只用了少数平面。Unicode 用数字-0x000000 -0x10FFFF来映射这些字符,其实原来uncode编码是0x0000 至 0xFFFF,也就是说2个字节,16位,后来不够了,又加了8位,也就是1个字节,不知道为什么,加的这一个字节本来可以使用ox00-oxFF中变化的,也就是说256种,不知道为什么只用了17种。也就是0x00-0x10。不过这17中已经只用了很少一部分,如果要有256中,估计要把外星人语言加进来才行了。

Unicode是编码规范,UTF-8UTF-16UTF-32都是将数字转换到程序数据的编码方案。UTF是"UCS Transformation Format"的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。对于字符'字',Unicode编码使用数字23383,也就是0x5b57。不论是使用UTF-8UTF-16UTF-32哪种编码,最终都要生成数字23383,只是采用不同的规则。

UTF-8:

UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如 下:
Unicode编码(16进制) ║ UTF-8 字节流(二进制)

  • 000000 - 00007F ║ 0xxxxxxx
  • 000080 - 0007FF ║ 110xxxxx 10xxxxxx
  • 000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx
  • 010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数 字。Unicode的最大码位0x10FFFF也只有21位。

对于字符'字',Unicode编码使用数字23383。使用UTF-8进行存储的时候,是oxE5AD97,三个字节。

它的二进制是:111001011010110110010111,可以按照上面的1110xxxx 10xxxxxx 10xxxxxx的规则进行拆分,拆分后把所有的x排成一行,就是:

0101101101010111

转换成10进制就是数字23383。

UTF-16

UTF-16编码以16位无符号整数为单位。我们把Unicode编码记作U。编码规则如下:
如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简 便,下文将16位无符号整数记作WORD)。 
如果U≥0x10000,我们先计算U'=U-0x10000,然后将U'写成二进制形 式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。

对于字符字符'字',使用数字23383,也就是ox5b57。

也就是你说UTF-16的大部分字符都是2个字节(16位),生僻字可能是4个字节(2个16位)。

也就是说16位是一个单元,并不是说每个字符都是16位。

java中的char是采用的UTF-16编码来描述一个代码单元的。

UTF-16有Big Endian Little Endian两种,代表在内存中,是高地址在前还是低地址在前,java采用的是Big Endian。对于字符字符'字',在内存中是101101101010111。如果是Little Endian,应该是反过来。

字符串型

从概念上讲,java的字符型就是unicode字符序列。

不可变:

一旦定义了一个字符串,就没有方法修改它。java没有提供修改字符串的方法,对于C程序来说,字符串相当于是个数组,你可以改变任何一个下标的值。但是Java不可以。

如果要对java字符串修改下标,只能新建一个字符串,然后通过substring和拼接来实现,这样一定程度上效率很低。

但是java设计者认为字符串修改操作很少,对于字符串的操作,大多是比较,和合并等操作。所以java设计者将字符串设置为不可变,然后实现了共享。

没有字符串是可变的,就不能实现共享:

可以想象将字符串放在一个公共的池中,字符串变量指向池中的值,如果复制一个字符串,源字符串和复制的字符串共享相同的位置。

java设计者认为共享带来的高效率远远胜过可修改的字符串。

检测相等:

因为不可变,所以不能用==,只能用equals。

因为String是对象,对于对象的比较,==在java中是用来比较对象指向的堆中的位置是否相同。

虽然如此,如果我们用=比较对象指向的堆中的位置是否一样,也是不可以。

  1. package com.zjf;
  2.  
  3. public class Test {
  4.  
  5.    public static void main(String[] args) {
  6.  
  7.       String s1 = "zhang";
  8.       String s2 = "zhang";
  9.       System.out.println(s1 == s2);
  10.    }
  11. }

结果为true。对我们来说,并没有做s1=s2的操作,结果却是true,这不是我们想要的结果。虽然说Sting a = b;那么用a == b是可以的,但是如果没有a=b,也可以a==b,这样对我们来说,会有不可预知的结果。

那么如果我们想用=来比较两个字符串的内容是否一致呢?也不行。

  1. package com.zjf;
  2.  
  3. public class Test {
  4.  
  5.    public static void main(String[] args) {
  6.  
  7.       String s1 = "zhang";
  8.       String s2 = "zhangjianfeng".substring(0, 5);
  9.       System.out.println(s1);
  10.       System.out.println(s2);
  11.       System.out.println(s1 == s2);
  12.    }
  13. }

结果为:

zhang

zhang

false

两个字符串都是zhang,使用=却没有比较成功。

原因是因为java虚拟机只对字符串常量进行共享,对于+和substring等操作产生的结果,是不会共享的。

使用==进行字符串比较,程序会出现bug,而且这种bug在一定程度上是随机的。不要使用。

代码点和代码单元

Java字符串由char序列组成,char是采用UTF-16编码表示Unicod代码点的代码单元。

代码点就是我们生活中面对的一个字,因为UTF-16的存储方式,对于某些代码点需要32位,也就是说两个代码单元来存储,在java中,一个char是一个代码单元。

这样就会造成一些误解。

首先,length方法返回的是代码单元的数量。而不是代码点的数量。

其次,charAt方法获取的是代码单元,不是代码点。如果想获取代码点,string提供的有codepoint方法,

如下代码:

作者说,避免使用char,因为这太低级了。其实,虽然很少见到这些特殊字符,使用char的场景还是要慎重。

构建字符串:

使用较短的字符串构建字符串:

  • StringBuilder
  • StringBuffer 线程安全

包引入问题

像Sting,Integer,StringBuilder这种包,位于java.lang目录下,不需要import引入,也能识别。

Java基本的程序结构设计 字符类型的更多相关文章

  1. Java基本的程序结构设计 基本类型的输入输出

    读取输入: java.util.Scanner 一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器. 了解: Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹 ...

  2. Java - 一道关于整型和字符类型相加的题目

    题目 public class Test { public static void main(final String[] args) { final int a = 10; final int b ...

  3. Java基本的程序结构设计 大数操作

    大数操作 BigInteger 不可变的任意精度的整数.所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型).BigInteger 提供所有 Java 的基本整数操 ...

  4. Java基本的程序结构设计 整形和浮点型

    整形: int 4字节 short 2字节 long 8字节 byte 1字节 int的大小差不多是20亿. 整形计算 如果两个int进行加减乘除数学运算的时候,最终的结果仍然是int,有可能出现了溢 ...

  5. Java基本的程序结构设计 数组

    声明数组: int[] a; int a[]; 两种方式.一般选择第一种,比较一目了然. 初始化,必须指定长度: int[] a = new int[10]; int[] a = {1,2,3}; 初 ...

  6. Java基本的程序结构设计 控制流程

    控制流程 java的控制流程和C和C++基本一致,只是不能使用goto语句,不过break语句可以带标签,实现从内层循环跳出的目的.标签可以放在for或者while前面.如下: package com ...

  7. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  8. Java开发笔记(三十一)字符类型的表达

    前面介绍的Java编程,要么是与数字有关的计算,要么是与逻辑有关的推理,充其量只能实现计算器和状态机.若想让Java运用于更广阔的业务领域,就得使其支撑更加血肉丰满的业务场景,而丰满的前提是能够表达大 ...

  9. java 基础 字符类型

    1.char类型的字面量可以是一个英文字母.字符或一个汉字,并且由单引号包括. 2.Java底层使用一个16位的整数来处理字符类型,该数值是一个字符的unicode编码值. unicode: 1.un ...

随机推荐

  1. CentOS mysql安装

    MySQL For Excel 1.3.5MySQL for Visual Studio 1.2.5MySQL Fabric 1.5.6 & MySQL Utilities 1.5.6Conn ...

  2. 文件分发服务器 AWS CloudFront(CDN)使用入门-以S3为例 Lebal:Research

    引言 在互联网上随意右击一张图片,都可以发现复制图片地址这个选项,这说明他们都有自己的链接(直链),也就是说我们可以通过一个链接本身来访问图片.代码等文件,而不是打开一个网页再选择复制,这就和下载链接 ...

  3. linux常用命令(22)gzip命令

    减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用.gzip不仅可以用 ...

  4. Unity中的动画系统和Timeline(5) Timeline

    在前面的动画,都是控制单独的物体,比如说控制一个角色的运动.而Timeline,可以对多个物体实施动画,形成过场动画,或者电影效果.比如,很多赛车游戏比赛开始前都会播放一段开场动画,围绕自己车的几个方 ...

  5. LeetCode.1037-有效的回旋镖(Valid Boomerang)

    这是小川的第387次更新,第416篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第248题(顺位题号是1037).回旋镖是一组各不相同且不在一条直线上的三个点.给出三个点 ...

  6. 转·带你用实例理解C语言回调函数

    原文出处:https://segmentfault.com/a/1190000008293902?utm_source=tag-newest 前言: 如不懂函数指针,请先查阅关于函数指针内容的资料(h ...

  7. Shell编程、part5

    本节内容 1. 三剑客简介 2. sed命令详解 3. awk命令详解 文本处理三剑客 在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具: |                 命令 ...

  8. lua基础学习(二)

    一,Lua变量   1.lua变量的三种类型:全局变量,局部变量,表中的域 Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量. 局部变量的作用域为从声明位置 ...

  9. Java初始和环境搭建

    前世今生 Java语言是什么? 一种计算机编程语言.名字取自咖啡. Java语言发展简史 Java语言之父:James Gosling SUN(Stanford University Network ...

  10. Hbase 三维存储

    hbase所谓的三维有序存储的三维是指:rowkey(行主键),column key(columnFamily+qualifier),timestamp(时间戳)三部分组成的三维有序存储. 1.row ...