知识框架
🏀数据类型
🥏数据类型的作用和分类
❤️数据类型用来声明变量,程序在运行过程中根据不同的数据类型分配不同大小的空间。
⭐️例如:int i = 10;double d = 1.23; i变量和d变量类型不同,空间大小不同!
❤️第一种:基本数据类型
⭐️基本数据类型又可以划分为4大类8小种:
第一类:整数型
byte,short,int,long
第二类:浮点型
float,double
第三类:布尔型
boolean:只有两个值true和false,true表示真,false表示假
第四类:字符型
char:java中规定字符型字面量必须使用单引号括起来;属于文字
⭐️8小种:byte,short,int,long,float,double,boolean,char
❤️第二种:引用数据类型
⭐️字符串型String属于引用数据类型;String字符串不属于基本数据类型范畴
⭐️java中除了基本数据类型之外,剩下的都是引用数据类型。
🥏不同数据类型占用的字节
类型 占用字节数量(byte) ------------------------------------ byte 1 short 2 int 4 long 8 float 4 double 8 boolean 1 char 2
❤️整数型:byte short int long有什么区别?浮点型:float和double有什么区别?
区别:占用的空间大小不同
❤️关于计算机存储单位?
⭐️计算机只能识别二进制。(1001101100...)
1字节 = 8bit(8比特)《---》 1byte = 8bit
1bit就是一个1或0.
1KB = 1024byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
⭐️例如:
byte b = 2; 在计算机中是这样表示的:00000010
short s = 2; 在计算机中是这样表示的:00000000 00000010
int i = 2;在计算机中是这样表示的:00000000 00000000 00000000 00000010
🥏取值范围
❤️例如:byte类型的取值范围是 [-128 ~ 127] 共可以标识256个不同的数字
⭐️byte类型的最大值是怎么计算出来的?
byte是1个字节,是8个比特位,所以byte可以存储的最大值是:01111111
⭐️注意:在计算机当中,一个二进制位最左边的是符号位,当为0时表示正数,当为1时表示负数。所以byte类型最大值是:01111111;就是。
⭐️有几个取值范围需要记住:
(1个字节)byte: [-128 ~ 127]
(2个字节)short:[-32768 ~ 32767] 可以表示65536个不同的数字
(4个字节)int: [-2147483648 ~ 2147483647]
(2个字节)char: [0~65535] 可以表示65536个不同的数字
⭐️short和char实际上容量相同,为什么表示的范围不同呢?
因为char表示的是文字,文字没有正负之分,可以看做是无符号数(>=0)的,取值范围就是:【】;而short表示的是数,有正负之分,是有符号数,取值范围是:【】
🥏字符编码
❤️对于8种基本数据类型来说:
⭐️其中byte,short,int,long,float,double,boolean这7种类型计算机表示起来比较容易,因为他们都是数字;其中布尔类型只有两个值true和false。
⭐️对于char类型来说计算机表示起来比较麻烦,因为char对应的是文字,每一个国家的文字不一样,文字不能直接通过“自然算法”转换成二进制。这就需要字符编码!
⭐️什么是字符编码?
字符编码是人为的定义的一套转换表。
在字符编码中规定了一系列的文字对应的二进制。
字符编码其实本质上就是一本字典,该字段中描述了文字与二进制之间的对照关系。
⭐️字符编码涉及到编码和解码两个过程,编码和解码的时候必须采用同一套字符编码方式, 如果编码和解码采用的不是同一个编码方式,会出现乱码!
⭐️最先支持的文字是英文,对应的字符编码方式是:ASCII码。ASCII码采用1byte进行存储,因为英文字母是26个。(键盘上所有的键全部算上也超不过256个。1byte可以表示256种不同的情况。所以英文本身在计算机方面就占优势。)
⭐️例如: 'a' --(采用ASCII码进行编码)-> 01100001
01100001 --(采用ASCII码进行解码)-> 'a'
'a' ---> 97 'A' ---> 65 '0' ---> 48
⭐️随着计算机语言的发展,后来国际标准组织制定了ISO-8859-1编码方式,又称为latin-1编码方式,向上兼容ASCII码。但不支持中文。
⭐️在java中,java语言为了支持全球所有的文字,采用了一种字符编码方式叫做unicode编码。unicode编码统一了全球所有的文字,支持所有文字。具体的实现包括:UTF-8 UTF-16 UTF-32....
⭐️需要记住:
ASCII('a'是97 'A'是65 '0'是48...)
ISO-8859-1(latin-1)
GB2312
GBK
GB18030
Big5(大五码,繁体中文)
unicode(utf8 utf16 utf32)
其中:GB2312<GBK<GB18030 (容量的关系)
🥏八种数据类型详解
整数型:byte、short、int、long
浮点型:float、short
布尔型:boolean
字符型:char
🥅字符类型:char
❤️char类型
⭐️例1:
1、char占用2个字节
2、char的取值范围:[0-65535]
3、char采用unicode编码方式
4、char类型的字面量使用单引号括起来
5、char可以存储一个汉字
public class CharTest01{ public static void main(String[] args){ //1.char存储1个汉字,一个汉字占用2个字节,java中的char类型占用2个字节,刚好 char c1 = '中'; System.out.println(c1); //2.存储一个英文字母 char c2 = 'a'; System.out.println(c2); //3.0如果加上单引号的话,0就不是数字0了,就是文字0,它是1个字符。 char c3 = '0'; System.out.println(c3); //4.错误: 不兼容的类型: String无法转换为char char c4 = "a";//err //5.错误: 未结束的字符文字 char c5 = 'ab';//err //6.错误: 未结束的字符文字 char c6 = '1.08';//err } }
⭐️例2:转义字符"\"
关于java中的转义字符java语言中“\”负责转义。例如:\t 表示制表符tab、 \n是换行等
public class CharTest02{ public static void main(String[] args){ //1.\t实际上是1个字符,不属于字符串 //两个字符合在一起表示一个字符,其中\t表示“制表符tab” char c2 = '\t'; //相当于键盘上的tab键 System.out.println("abc\tdef");//打印abc def //2.println和print的区别 System.out.println(); // 换行 System.out.print(); // 不换行 //3.\n表示换行;所以print+\n的效果实际上就等价于println System.out.println(); <===> System.out.print()+ System.out.print("\n") //4.利用转义字符"\";输出具有特殊意义的字符 //4.1假设现在想在控制台输出一个 ' 字符怎么办? System.out.println('\''); //4.2假设现在想在控制台输出一个 \ 字符怎么办? System.out.println('\\'); //4.3双引号括起来的是字符串;希望输出的结果是:"test" System.out.println("\"test\""); System.out.println("“test”"); //内部的双引号我用中文的可以 //5.\u表示后面的是一个字符的unicode编码;unicode编码是十六进制的 char x = '\u4e2d'; System.out.println(x); // '中',因为'中'的unicode码对应的就是4e2d } }
补充:如何实现把一个汉字找到对应的unicode码?
利用bin目录下的native2ascii.exe命令,输入后回车;输入中文汉字回车,就会自动转换为对应的unicode码!
⭐️例3:
1、当一个整数赋值给char类型变量的时候,会自动转换成char字符型,最终的结果是一个字符。例如:char i = 97;打印出来的是字符‘a’
2、当一个整数int没有超出byte short char的取值范围的时候,这个整数可以直接赋值给byte short char类型的变量
public class CharTest03{ public static void main(String[] args){ //1.这里会做类型转换;97是int类型(默认当做int处理);c2是char类型 char c2 = 97; System.out.println(c2); // 'a';根据ASCII码输出对应的值 //2.char类型取值范围:[0~65535] char c3 = 65535; // 实际上最终是一个“看不懂”的字符;但不会报错! System.out.println(c3); //3.错误: 不兼容的类型: 从int转换到char可能会有损失 char c4 = 65536;//err,超过char的取值范围会报错! //怎么解决以上问题?进行强制类型转换! char c4 = (char)65536;//超过范围就进行强制类型转换 } }
🥅整数型类型:byte、short、int、long
❤️int类型和long类型
⭐️若long类型的字面量没有超过int类型的取值范围,也不能直接编译成功,必须要进行强制类型转换;例如:int x = 10L(err);int x = (int)10L(才正确)
⭐️例1
在java语言中整数型字面量有4种表示形式:十进制、二进制(0b)、八进制(0)、十六进制(0x)
public class IntTest01{ public static void main(String[] args){ //1.十进制 int a = 10; System.out.println(a); // 10 //2.八进制,以0开头 int b = 010; System.out.println(b); // 8 //3.十六进制,以0x开头 int c = 0x10; System.out.println(c); // 16 //4.二进制方式,以0b开头;二进制(JDK8的新特性,低版本不支持。) int d = 0b10; System.out.println(d); // 2 } }
⭐️例2:自动类型转换---小容量转换成大容量
1、重要的结论:在任何情况下,整数型的“字面量/数据”默认被当做int类型处理。
2、如果希望该“整数型字面量”被当做long类型来处理,需要在“字面量”后面添加L/l
public class IntTest02{ public static void main(String[] args){ //1.不存在类型转换 // 100这个字面量被默认当做int类型处理; // a变量也是int类型,所以不存在类型的转换。 // int类型的字面量赋值给int类型的变量! int a = 100; System.out.println(a); //2.存在类型转换(自动类型转换) // 200这个字面量默认被当做int类型来处理; // b变量是long类型,int类型占4个字节,long类型占8个字节 // 小容量可以自动转换成大容量,这种操作被称为:自动类型转换。 long b = 200; System.out.println(b); //3.不存在类型转换。 // 在整数型字面量300后面添加一个L之后,300L联合起来就是一个long类型的字面量 // c变量是也long类型,long类型赋值给long类型不存在类型转换。 long c = 300L; System.out.println(c); //4.存在类型转换(自动类型转换) // 2147483647默认被当做int来处理 // d变量是long类型,小容量可以自动赋值给大容量,自动类型转换 long d = 2147483647; //2147483647是int最大值。 System.out.println(d); //5.编译器会报错,为什么? // 在java中,整数型字面量一上来编译器就会将它看做int类型 // 而2147483648已经超出了int的范围,所以在没有赋值之前就出错了。 // 不是e放不下2147483648,e是long类型,完全可以容纳2147483648 // 只不过2147483648本身已经超出了int范围。 long e = 2147483648; System.out.println(e);// 错误: 整数太大,要想正常云运行,后面加上L即可 } }
⭐️例3:强制类型转换---大容量转小容量
1、小容量可以直接赋值给大容量,称为自动类型转换。
2、大容量不能直接赋值给小容量,需要使用强制类型转换符进行强转。
注意:加强制类型转换符之后,虽然编译通过了,但是运行的时候可能会损失精度
public class IntTest03{ public static void main(String[] args){ //1.不存在类型转换 // 100L是long类型字面量,x是long类型字面量。 long x = 100L; //2.x是long类型,占用8个字节,而y变量是int类型,占用4个字节 // 编译错误信息:错误: 不兼容的类型: 从long转换到int可能会有损失 int y = x;//err //3.大容量转换成小容量,要想编译通过,必须加强制类型转换符,进行强制类型转换。 //long类型100L:00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100100 //会自动将“前面”的4个字节砍掉:00000000 00000000 00000000 01100100 int y = (int)x; //4.这个(int)就是强制类型转换符,加上去就能编译通过。但是编译虽然过了,但是运行时可能损失精度。 System.out.println(y); // 100 } }
❤️byte类型和short类型
⭐️理解:若int类型的字面量没有超过char、byte和short类型的取值范围,就算不用强制类型转换也能正常编译;例如:byte x = 10(默认是int类型)、short y = 100(默认是int类型);
⭐️总结:当一个整数型的字面量没有超出 byte,short,char 的取值范围,可以将该字面量直接赋值给byte,short,char 类型的变量,如果超出范围则需要添加强制类型转换符。
⭐️特殊情况:例如:int x = 10,byte y = x还是会编译报错,因为编译器只能检测到右边是int类型,不知道具体字面量是多少;所以int类型数据用byte类型来存储就有可能缺失精度;所以会报错!
⭐️例1:
当这个整数型字面量没有超出当前变量的取值范围,那么这个整数型字面量可以直接赋值给当前类型的变量。
public class IntTest04{ public static void main(String[] args){ //1.300被默认当做int类型b变量是byte类型 // 大容量转换成小容量,要想编译通过,使用强制类型转换符 // 错误: 不兼容的类型: 从int转换到byte可能会有损失 byte b = 300;//err,300超过了byte的范围 //2.要想让以上的程序编译通过,必须加强制类型转换符 //虽然编译通过了,但是可能精度损失。 // 00这个int类型对应的二进制:00000000 00000000 00000001 00101100 //byte占用1个字节,砍掉前3个字节,结果是:00101100 (44) byte b = (byte)300; System.out.println(b); // 44 //3.当整数型字面量没有超出byte类型取值范围的时候,该字面量可以直接赋值给short byte x = 1; byte y = 127;//默认都是int类型,的那都没有超过byte的取值范围,不会报错 //错误: 不兼容的类型: 从int转换到byte可能会有损失 byte z = 128;//超出byte的范围了,会编译报错 //4.当整数型字面量没有超出short类型取值范围的时候,该字面量可以直接赋值给short类型的变量。 short s = 1; short s1 = 32767; System.out.println(s);//正常输出 //错误: 不兼容的类型: 从int转换到short可能会有损失 short s2 = 32768;//err,超过short的取值范围 } }
⭐️例2:补充原码、反码、补码
10010110 ---> 二进制补码形式 10010101 ---> 二进制反码形式 11101010 ---> 二进制原码形式 public class IntTest05{ public static void main(String[] args){ //编译报错:因为150已经超出了byte取值范围,不能直接赋值,需要强转 //byte b = 150;//err byte b = (byte)150; //10010110,正数:原码、反码、补码同 //10010101,反码,补码-1就是反码 //11101010,原码,反码符号位不变,其它位取反 //或者可以直接用补码继续取反+1,10010110->11101001->11101010也能得到原码 //最高位是符号位,所以最终结果是:-1101010 = -106 System.out.println(b); // -106;也就是150-256=-106 } }
❤️byte、char、short混合运算
⭐️例1:
byte、char、short做混合运算的时候,各自先转换成int再做运算,最终结果就是int类型(相当于C语言中的整型提升)
public class IntTest06{ public static void main(String[] args){ //1.都会先转换为整型数据,然后在进行求和计算;最终结果也是整型 char c1 = 'a'; byte b = 1; System.out.println(c1 + b); // 98 //2.错误: 不兼容的类型: 从int转换到short可能会有损失;这样为什么会报错呢? //编译器不知道这个加法最后的结果是多少。只知道是int类型;所以可能会超过short范围,所以报错 //short s = c1 + b; //err short s = (short)(c1 + b);//这样修改强制类型转化一下就可以了 //3.直接写成short x = 1可以;下面这种形式不可以,编译器只知道a是int类型,不知道a中存储的是哪个值。 //错误: 不兼容的类型: 从int转换到short可能会有损失 int a = 1; short x = a; System.out.println(x);//err,编译不过去 } }
⭐️例2:
1、多种数据类型做混合运算的时候,最终的结果类型是“最大容量”对应的类型
2、char+short+byte 除外;char + short + byte混合运算的时候,会各自先转换成int再做运算;所以对应的最大容量就是int类型!
public class IntTest07{ public static void main(String[] args){ //1.最终结果的类型是long类型,提升到最大容量的类型 long a = 10L; char c = 'a'; short s = 100; int i = 30; System.out.println(a + c + s + i); //237,结果是long类型 //2.要想用int接收,必须强制类型转换;计算结果是long类型 //错误: 不兼容的类型: 从long转换到int可能会有损失 //int x = a + c + s + i;//err int x = (int)(a + c + s + i);//强制类型转换 System.out.println(x); } }
🥅浮点型类型:float、double
⭐️例1:
1、浮点型包括:float是单精度占4个字节;double是双精度占8个字节;
2、注意:如果用在银行方面或者说使用在财务方面,double也是远远不够的,在java中提供了一种精度更高的类型,这种类型专门使用在财务软件方面:java.math.BigDecimal (不是基本数据类 型,属于引用数据类型)
3、float和double存储数据的时候都是存储的近似值。
4、long类型占用8个字节,float类型占用4个字节;哪个容量大?
注意:任意一个浮点型都比整数型空间大;float容量 > long容量。
5、java中规定,任何一个浮点型数据默认被当做double来处理。如果想让这个浮点型字面量被当做float类型来处理,在字面量后面添加F/f。
6、如果想要得到一个float类型 的浮点数,必须要强制类型转换或者在数据后面加上F/f才可以,不然就会编译报错!不是像byte、short、char类型一样,默认数据是int类型,数据只要没超过byte、short、char类型范围,就能直接赋值过去!
public class FloatTest01{ public static void main(String[] args){ //1.这个不存在类型转换,3.1415926是double类型,pi是double类型 double pi = 3.1415926;//默认是double类型 System.out.println(pi); //2.错误: 不兼容的类型: 从double转换到float可能会有损失 float f = 3.14; //修改方法1:3.14f或者3.14F //修改方法2:强制类型转换,但可能损失精度。谨慎使用。 float f = (float)3.14; System.out.println(f); //3.错误: 不兼容的类型: 从double转换到int可能会有损失 //原理:先将5转换成double类型,然后再做运算,结果是double,大容量无法直接赋值给小容量,需要强转。 int i = 10.0 / 5; //修改方法1: int i = (int)10.0 / 5; System.out.println(i); // 2 //修改方法2: int x = (int)(10.0 / 5); System.out.println(x); // 2 } }
🥅布尔型类型:boolean
⭐️例1:
1、在java语言中boolean类型只有两个值,没有其他值:true和false。
不像C或者C++,C语言中1和0也可以表示布尔类型。
2、boolean类型在实际开发中使用在逻辑判断当中,通常放到条件的位置上(充当条件)
public class BooleanTest01{ public static void main(String[] args){ //1.错误: 不兼容的类型: int无法转换为boolean //boolean xingBie = 1;//1并不能代表true //2.如果为true则表示男,为false则表示女。 boolean sex = true; if(sex){ System.out.println("男"); }else{ System.out.println("女"); } //3.判断大小,输出的是true或false;而不是1或0 int a = 10; int b = 20; System.out.println(a < b); // true System.out.println(a > b); // false } }
总结:
⭐️八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以进行转换;
⭐️如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给
byte,short,char 类型的变量;
⭐️小容量向大容量转换称为自动类型转换,容量从小到大的排序为:byte < short(char) <
int < long < float < double,其中 short 和 char 都占用两个字节,但是 char 可以表示更大
的正整数;
⭐️大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但运行时可能出现精度损失,谨慎使用;
⭐️byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
⭐️多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;
🥅小试牛刀
⭐️例1
public class TypeTransferTest{ public static void main(String[] args){ //1.编译报错,因为1000已经超出byte的范围(-128~127)了 byte b1 = 1000; //2.可以 byte b2 = 20; //3.可以 short s = 1000; //4.可以 int c = 1000; //5.可以 long d = c; //6.编译报错,d是long型,放到int型需要强制类型转换 //int e = d; int e = (int)d; //7.可以 int f = 10 / 3; //8.可以 long g = 10; //9.编译报错,g是long型,最终结果也是long型,放到int型需要强制类型转换 //int h = g / 3; int h = (int) (g / 3); //10.可以 long m = g / 3; //11.编译报错,g虽然强制类型转换了,但是3还是整型,最终结果就是整型,放到byte需要强制类型转换 //byte x = (byte)g / 3; byte x = (byte)(g / 3); //12.可以 short y = (short)(g / 3); //13.可以 short i = 10; //14.可以 byte j = 5; //15.编译报错,只能检测出i+j结果是整型,整型放到short来接收,会编译报错 //short k = i + j;//这里换成15就可以的 //16.可以 int n = i + j; //17.可以 char cc = 'a'; System.out.println(cc); // a //最终结果强制类型转换为byte,属于整型,结果也没有超出byte的范围,结果是97 System.out.println((byte)cc); //97 //18.cc会先自动转换成int类型,也就是97,最后再做运算 int o = cc + 100; System.out.println(o); // 197 } }
⭐️例2:short s1 = 1; s1 = s1 + 1;有什么错?
s1 是 short 类型,1 是 int 类型,short 和 int 混合运算的时候 short 会自动转换为 int 类型, 所以 s1 + 1 编译器检测出是 int 类型,int 类型无法赋值给 short 类型的变量 s1。这样修改:s1 = (short)(s1 + 1);
⭐️例3:char 类型变量能不能储存一个中文的汉字,为什么?
java 中的文字采用 unicode 编码,一个中文占用 2 个字节,char 类型在 java 中就是占用两个字节,所以 java 中的 char 类型完全可以容纳一个汉字。
⭐️例4:float f = 1.0 有什么错?
1.0 字面量被当做 double 类型处理,大容量 double 无法赋值给小容量 float。这样修改,两 种方案:第一种方案是 1.0 后面添加 f/F。第二种方案是强制类型转换:float f = (float)1.0;
⭐️例5:long a = 2147483648 有什么错?
不是 long 类型存不下 2147483648,而是 java 把 2147483648 当做 int 类型来处理,但本身 已经超出 int 类型范围。这样修改:long a = 2147483648L;
⭐️例6:int i = 0xffff 有问题吗?
没有问题:0xffff 以 0x 开始表示十六进制表示方式,ffff 转换成十进制是:65535
⭐️例7:char c = 65536 有问题吗,为什么?
65536 已经超出 char 类型取值范围,不能直接赋值,这样修改:char c = (char)65536;