概述
java八大基本数据类型byte,short,int,long,float,double,char,boolean,他们分别对应有各自的封装。java为啥要保留基本数据类型?因为基本数据类型常用且存于栈中,占用空间少,性能比使用对象好,且基本数据类型有默认值,而对象的默认值为null。为啥还要有class对象和基本数据类型对应呢?因为java是面向对象语言,基本数据类型的存在是因为性能的优势,与之对应的包装类就是为了符合面向对象开发,特别是在实现了自动装箱拆箱操作以后。
获取基本数据类型
-
通过Class.getPrimitiveClass("byte")获取byte.class类型
-
Byte.class==byte.class返回false
-
Class.getPrimitiveClass("byte")==byte.class返回true
装箱拆箱
代码如下
public void packingAndUnboxing(){
int a=1;
Integer b=2;
a=b;
}
执行 javap -c className.class 得出如下图
解析字节码
-
行标0-1是对int a=1的解析,对基本数据类型赋值
-
行标2-3是对Integer b=2的解析,注意后面有一个Integer.valueOf(),意味这这句正确执行的是Integer b=Integer.valueOf(2),需要验证的可以在valueOf方法中断点调试
-
行标6-8是执行a=b这里实际执行的代码是a=b.intValue()
java的自动装箱拆箱是由编译器就处理好的
基本类型对应封装类的缓存
在某些封装类中,定义了内部类作为缓存即实例化时不会去new,直接取缓存中的数据,我们可以看看这样一段代码
Integer a=1;
Integer b=1;
a=b?
答案是a=b,即使a,b都是对象,前面我们已经说过Integer a=1实际上是Integer a=Integer.valueOf(1),方法源码如下
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
也就是说如果我们的值在缓存最小值和最大值之间,那么就直接使用缓存中的值,不会去new,a,b使用的同一个缓存自然相等。
那么有哪些封装类型具有缓存呢
-
Byte缓存范围为-128到127,
-
Short缓存范围-128到127
-
Integer默认缓存范围-128到127,可设置最大值,如:在VM中加入-Djava.lang.Integer.IntegerCache.high=1000,最大值就为1000
-
Long缓存范围-128到127
-
Character缓存范围0-127
Character范围0-127是缓存常用的ASCII字符,范围-128到127表示一个字节,因此缓存几乎也是这个范围。详情请看计算机存储数据的格式
不管是否有缓存,使用new关键字创建的都不会使用缓存中的数据,如Integer a=1和Integer b=new Integer(1)不等
欢迎加入学习交流群569772982,大家一起学习交流。