一、认识各种编码方式

ASCII 码

ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,英文名为 America Standard Code for Information Interchange 即美国信息交换标准码表。ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

缺点:

  • 不能表示所有字符。
  • 相同的编码表示的字符不一样:比如,130在法语编码中代表了é,在希伯来语编码中却代表(ג) 了字母Gimel

Unicode 编码

Unicode码表:万国码,也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但是从128开始包含有更多的字符,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用 Unicode 没有乱码的问题。(java语言默认使用的编码表)

缺点:Unicode 只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储:无法区别 Unicode 和 ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费。

UTF-8

UTF-8 是一种变长的编码方式。它可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。

UTF-8的编码规则:

对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)。

对于多字节的UTF-8编码,如果编码包含 n 个字节,那么第一个字节的前 n 位为1,第一个字节的第 n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为"10",其余6位用来对字符进行编码。

乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

二、基本数据类型转换

自动类型提升(隐式)

特点:代码不需要进行特殊处理,自动完成。

容量小的类型自动转换为容量大的数据类型。数据类型按容量大小(容量大小指的是数表示的范围,并非占用内存空间的大小)排序为:

Java byte可以转换为double javabyte转化为string_byte转换为string乱码

有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。

byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。

boolean类型不能与其它数据类型运算。

自动类型提升的特殊情况:

在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果。

例如:short result=5+8;

等号右边全都是常量,没有任何变量参与运算编译之后,得到的.class字节码文件当中相当于【直接就是】:

short result=13;

右侧的常量结果数值,没有超过左侧范围,所以正确。这称为“编译器的常量优化”。但是注意:一旦表达式当中有变量参与,那么就不能进行这种优化了。

//情况一:byte b1 =1;byte b2 =2;byte b3=b1+b2;System.out.println(b3);//编译报错 错误:不兼容的类型 可能会溢出(计算机在解释运行时才会在内存中开辟空间,但编译的时候计算机不知道这个变量的值)

注:(情况一中的byte、short、char替换为int或者long则不会报错,因为本身范围大,相当于java给的特权)

//情况二:byte b1 =1;byte b2 =b1+2;System.out.println(b2);//编译报错 错误:不兼容的类型 可能会溢出(计算机在解释运行时才会在内存中开辟空间,但编译的时候计算机不知道这个变量的值

即假设b1的值是127这种临界值,还是不会超,但是一相加的值就不确定就可能溢出。即右边是常量就可以做自动转换,右边如果是变量就不做自动转换,因为做了自动转换就可能带来精度的丢失。)

byte b1=2;b1+=5;System.out.println(b1);

编译正确,复合赋值运算符其中隐含了一个强制类型转换。+=是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。

•特例

对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char)。

1.如果没有超过左侧的范围,编译器补上强转。

2.如果右侧超过了左侧范围,那么直接编译器报错。

• 可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,只要不超出其表数范围

//情况三:byte b =126+1;System.out.println(b);//编译正确
//情况四:byte b = 127+1;System.out.println(b);//编译报错 超出byte的范围

强制类型转换(显式转换)

特点:代码需要进行特殊的格式处理,不能自动完成。

格式:范围小的类型 范围小的变量名=(范围小的类型)原本范围大的数据  

注:强制类型转换时右边转换类型必须用小括号括起来

boolean类型不可以转换为其它的数据类型。

自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符:(),但可能造成精度降低或溢出,格外要注意。

通常,字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换成基本类型。

String a = “43”; int i = Integer.parseInt(a);

精度损失举例

int i2 = 128;byte b = (byte)i2;System.out.println(b);//-128

字符串类型:String

String不是基本数据类型,属于引用数据类型

使用方式与基本数据类型一致。例如:String str = “abcd”;

一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。当把任何基本数据类型(包括布尔型)的值和字符串(String)进行连接运算且只能是连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型。例如:

str = str + “xyz” ;int n = 100;str = str + n;

常见字符串和其他数据类型拼接练习举例:

char c='a';int num=10;String str="hello";System.out.println(c+num+str);//107helloSystem.out.println(c+str+num);//ahello10System.out.println(c+(num+str));//a10helloSystem.out.println(str+num+c);//hello10a

练习:

//输出:* *System.out.println("* *");//* *System.out.println('*'+'\t'+'*');//93System.out.println('*'+"\t"+'*');//* *System.out.println('*'+'\t'+"*");//51*System.out.println('*'+('\t'+"*"));//* *