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. python 提示 :OverflowError: Python int too large to convert to C long

    一次在使用orm进行联表查询的时候,出现   Python int too large to convert to C long 的问题: 在分析错误之后,在错误最后面提示中有: File " ...

  2. 阶段3 2.Spring_04.Spring的常用注解_7 改变作用范围以及和生命周期相关的注解

    Scope 改成多例 PreDestory和PostConstruct PreDestory和PostConstruct这两个注解了解即可 增加两个方法,分别用注解 没有执行销毁方法. 如果你一个子类 ...

  3. 跨域请求配置 Amazon AWS S3 腾讯云 阿里云 COS OSS 文件桶解决方案以及推荐 Lebal:Research

    跨域请求配置 跨域请求指的就是不同的域名和端口之间的访问.由于 ajax 的同源策略影响.跨域请求默认是不被允许的. 使用@font-face外挂字体时,可能遇到跨域请求CROS问题:F12控制台报错 ...

  4. elasticsearch-6.2.3单机搭建

    1.这里说明下,elasticsearch为了保证安全性需要创建新的用户名,需要在新的用户名下运行,本人用的是elasticsearch-6.2.3,centos7.3 2.切换目录到:cd usr/ ...

  5. 【react】input输入框可输入的最好实现方式

    使用的是refs.react中输入框不能直接定义value.输入框是可变的,react会提示报错.需要使用的inChange事件(输入框内容被改变时触发). 要定义输入框初始值,需要在componen ...

  6. 一本值得你反复研读的Python佳作《Python编程从0到1》

    现在的Python入门书太多太多了,究竟如何选择呢? 当然选最好的最入门的讲解最清晰的,没有那么多废话的. 现在就推荐一本<Python编程从0到1>,还带视频的,到时候跟大家一起学习沟通 ...

  7. SQL子连接案例

    子查询 何时使用子查询 1. 子查询作为数据源 2. 数据加工 需求:根据不同顾客的所有的账户余额划分区间,进行分组 sql语句实现如下: select 'Small Fry' name , 0 lo ...

  8. Docker&Java&Mysql&Python3&Supervisor&Elasticsearch安装

    目录 docker 安装java 安装mysql 安装Mysql8 安装python3 安装supervisor 安装ElasticSearch 打包images docker yum install ...

  9. Java Calendar使用

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  10. PostgreSQL-UNION与Order by 冲突

    问题描述 union 连接的两个sql 都包含 order SELECT <property1>, <property2> FROM <table1> ORDER ...