提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
学习完一遍javase后回来二刷对java数据类型笔记的整理
一、java有什么数据类型
java大致有两种数据类型分别为基本类型和引用类型。
要掌握基本类型8种和重点掌握引用类型的String字符串处理
二、4种整形
1.大小关系和范围
- byte: 8位有符号整数 (-128 到 127)
- short: 16位有符号整数 (-32,768 to 32,767)
- int: 32位有符号整数 (-2,147,483,648到2,147,483,647)
- long: 64位有符号长整型 (-9,223,372,036,854,775,808L到9,223,372,036,854,775,807L)
- 注意:long类型数据尾部要加L修饰,不然默认为整形类型数据的默认类型int(下面说到的浮点类型也一样,float和double(默认),float数据尾部要用F修饰)
2.类型提升和类型强转
类型提升:从上面idea爆红的提示可知byte+byte、byte+short、short+short无论相加有没有超过他们自身的大小范围都会直接转化为int(默认)
//类型强转
int d = 1;
byte d1 = (byte)d;
short d2 = (short) d;
类型强转:简单记就是大范围转为小范围
3.注意事项
A、基础数据类型之间尽量不做强转
B、基础数据类型强转时,注意数据越界问题
//强转后可能会丢失数据
int e = 128;
byte e1 = (byte)e;
System.out.println(e1);//-128 明显丢失了原本的数据
C、不同类型运算时,结果自动转为大类型;
就是两个大小不同的类型相加,结果转化为大的类型。
int h = 1;
long i = 922337203685477580L;
//int j = h+i;//爆红,不允许
long j = h+i;
System.out.println(j);//922337203685477581
4.误区
类型自动提升是对于short和byte的,byte、short运算时,如:+/-等提升为int。
还有上面提到的两数不同类型运算时,小范围会提升为相同的大范围后操作。
容易搞错的点:
其他整形类型数据相加如果大小范围超出大类型的范围就会丢失数据,结果只能在两个操作数的大范围上。示例如下:
int f = 2147483647;
int g = 1;
long l = f+g;//两个int相加,结果还是int类型,跟谁接收没关系
System.out.println(l);//-2147483648 数据丢失
long k = 9223372036854775807L;
long m = k+g;//int+long相加,结果大范围是long类型
System.out.println(m);//-9223372036854775808 数据丢失
三、8种基本类型
1.Float和Double浮点类型
float是单精度小于double双精度
java浮点数常量的默认类型是 double 型,1.23默认是double,所以
Float a = 1.23F//对的,1.23F 被F修饰,不能默认是double类型,已经是float类型,可以直接赋值
Float a = 1.23//是错误的,1.23是double
double要赋值给float就必须要类型强转(大范围转向小范围)
Float a = (float)1.23//对的,也可以这样
范围大小:double>float>long>int>short>byte
类型提升(跟前面说的一样):
A.float可自动提升为double(默认)
B.整型类型(4种)与float/double运算时,结果会自动提升为float/double类型
C.float与double运算时,结果会自动提升double类型
类型强转:一样的,大范围转向小范围。注意:会丢失精度
2.Char字符类型
可以注意到上表显示的数字区间,这些其实是字符所代表的Unicode编码的数值,所以Char类型的变量可以有两种赋值方式,一种是用单引号
引起来的一个字符,如 ‘e’、E’。另一种是ASCII码的值。
ASCII码表链接Ascll完整码表(256个)_ascll码表-CSDN博客
char a = 65;
System.out.println(a);//输出A
char b = 'A';
System.out.println(b);//输出A
两个Char类型的变量的相加就是ASCII码值的相加。
范围大小:double>float>long>int>char>short>byte
类型提升:
A.char与char运算时,结果会自动提升为int类型
B.char与int/longfloat/double运算时,结果会自动提升为int/long/float/double类型
类型强转:一样的,大范围转向小范围。char->short,byte
3.总结
double>float>long>int>char>short>byte
类型提升(小->大):
过小的直接提升到默认类型(int、double),否则提升到大范围的同伴操作数
A、byte->int、long、float、double;
B、short->int、long、float、double;
C、int->long、float、double;
D、long->float、double;
E、float->double;
F、double:无可自动提升类型;
G、char->int、long、float、double;
H、boolean:不支持类型提升;
类型强转(向下转型:大->小):
A、byte:除boolean外,其它类型均可强转为byte;
B、short:除boolean,byte外,其它类型均可强转为short;
C、int:除boolean,byte,short,char外,其它类型均可强转为int;
D、long:除boolean,byte,short,char,int外,其它类型均可强转为int;
E、float:除boolean,byte,short,char,int,long外,其它类型均可强转为float;
F、double:除boolean,byte,short,char,int,long,float外,其它类型均可强转为double;
G、char:除boolean,byte,short外,其它类型均可强转为char;
H、boolean:不支持类型强转;
4.补充
在《Java虚拟机规范》中有提到:Java语言表达式所操作的boolean,编译后均使用Java虚拟机中的int数据类型来代替,比如:使用0和1来表示true和false,也就是int类型,所以这种实现占用4个字节;boolean数组将会被编码成Java虚拟机的byte数组,每个boolean元素占8位,可得出boolean单独使用占4字节,在数组中占1个字节。
四、包装类与基础类型
java是面向对象的编程语言,实际业务中要对数据进行操作,需要转化为对象存储操作,包装类提供许多方法方便处理数据等。
1.区别A
A、包装类型可为null,基础类型不可,运行时会报空指针异常。
Integer i1=null;
int in = i1;报空指针异常
System.out.printf("in: %s\n",in)
B、包装类型可为泛型,基础类型不可,编译时会报错。
C、基础类型比包装类型更高效,成本更低:基础类型在栈中存储,包装类型数据存储在堆中,而栈中存储了包装类型在堆中引用,所以基础类型占用内存更少,并且栈存取速度远高于堆。
D、两个包装类型值可能相等,但却不相等。
Integer i2= new Integer(8);
Integer i3 =new Integer(8);
System.out.printf(” i2 == i3: %s\n",i2 == i3);//F,比较的是对象的地址
System.out.printf(” i2 equal i3:%s\n",i2.equals(i3));//T,比较的是对象的值
i2==i3:比较的是包装类型在堆中的引用地址,可能不相同;
i2.equals(i3):比较包装类型对应基础类型的值,所以一定相等;
2.自动装箱和自动拆箱
A.自动装箱
基本类型直接赋值给对应的包装类型
int a = 1;
Integer b = a;//基本类型直接赋值给对应的包装类型
B.自动拆箱
包装类型直接赋值给对应的基本类型
Integer a = 100;//自动装箱
int b = a;//自动拆箱
3.比较(==/equal())
A、自动装箱时,若数字在-128~127之间,直接使用缓存中的对象,无需重新创建。若使用lntegerCache缓存的对象,对象间使用==比较时会返回true,如果数字不在-128~127之间,则创建新对象,此时==比较时返回false。
B、基础类型与包装类型==比较时,包装类型自动拆箱,然后比较基础类型值:
int i5 = 4;
Integer i6 = 4;
System.out.printf("i5 == i6: %s\n", i5 == i6);//true
C、包装类型与包装类型==比较,数值小于127,自动装箱,从缓存IntegerCache获取数值比较,返回true:
Integer i7 = 127;
Integer i8 = 127;
System.out.printf("i7 == i8: %s\n", i7 == i8);//true
D、包装类型与包装类型==比较时,数值大于127,自动装箱,此时不从缓存获取,直接创建新对象,此时比较返回false:
Integer i9 = 128;
Integer i10 = 128;
System.out.printf("i9 == i10: %s\n", i9 == i10);//false
E、实际开发中,包装类型的比较要用equals比较,因为比较的是存放在堆中的实际值,如下:
Integer i11 = 128;
Integer i12 = 128;
System.out.printf("i11 equals i12:%s\n",i11.equals(i12));//true
注意:整型及字符类型均提供了相关Cache优化,其中只有lntegerCache的缓存上限可通过虚拟机参数-XX:AutoBoxCacheMax来设置。
五、引用类型(String、普通类、接口、数组)
其实上面介绍到的包装类就是引用类型的数据,就是后面我们学到的类class,存放在JVM的堆内存中,每创建一个对象,就会有一个明确的引用地址表明对象在堆内存中的位置,而基本类型的数据存放在栈中无法扩展。
String是引用类型数据的一个重点,要重点掌握对字符串的处理,下节再详细介绍。