Java语言是一种面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,设计者将每个基本数据类型单独封装成一个类,这八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
Java语言提供了八种基本类型。六种数字类型(四个整数型(默认是int 型),两个浮点型(默认是double 型)),一种字符类型,还有一种布尔型。
1.byte: byte数据类型是8位、有符号的,以二进制补码表示的整数;(256个数字),占1字节
2.short: short数据类型是16位、有符号的以二进制补码表示的整数,占2字节
3.int: int数据类型是32位、有符号的以二进制补码表示的整数;占4字节
4.long: long数据类型是64位、有符号的以二进制补码表示的整数;占8字节
这里需要注意下:
应该这想写long a = 100000L,int b = -200000L。
long a=111111111111111111111111(错误,整数型变量默认是int型)
long a=111111111111111111111111L(正确,强制转换)
5.float: float数据类型是单精度、32位;占4字节 -3.4E38- 3.4E38。。。浮点数是有舍入误差的(注意:浮点数比较大小时不能用==号)
例子:float f1 = 234.5f。
float f=6.26(错误 浮点数默认类型是double类型)
float f=6.26F(转换正确,强制)
double d=4.55(正确)
6.double: double数据类型是双精度、64位、符合IEEE 754标准的浮点数;占8字节
7.char:char类型是一个单一的16位Unicode字符;用 ‘’表示一个字符。2字节
8.boolean: boolean数据类型表示一位的信息;只有两个取值:true和false;大小有三种说法。。
进入正题
什么是自动拆箱与自动装箱?
举个例子:
- Integer i = new Integer(0);
- Integer j = 2;
- Integer j = Integer.valueOf(2);
上面的三行代码第一行是最基本的创建一个integer对象的方式,也就是装箱的过程。第二行代码就是我们这里要讲的自动装箱。而第三行代码就是第二行代码的本质,也就是说,当你使用自动装箱来得到一个引用数据类型时,jvm实际上调用了valueOf()方法
下面看看自动拆箱
自动拆箱:跟自动装箱的方向相反,将Integer这样的包装类的对象重新简化为基本类型的数据
Integer i=20;
System.out.println(i>10);
int j=i+2;
这句代码就使用了自动拆箱。i是我们上面通过自动装箱得到的一个integer对象,而这个对象是不能直接进行四则运算和==操作,但是我们让它和10比大小,这样就必须将integer对象转变为基本数据类型(int),这个过程就是自动拆箱的过程
需要注意:
所谓自动,就是说这个过程并不需要程序员去完成,而是jvm自动完成的,jvm会在编译期根据语法决定是否进行装箱和拆箱动作。另外,自动拆箱与自动装箱的jdk1.5才引入的新特性,所以如果你的jdk版本低于1.5的话,是不可以这样写的。
为什么java要提供这样一个功能呢?
1.简洁。假如没有自动拆箱与自动装箱,那么我们的代码是这样的:
Integer i =new Integer(2);//假如需要一个integer的对象i,值为2
int b=i.intValue();//又需要一个int型的值,大小与i相等
但是,有了自动拆箱与装箱,我们就可以这么写:
Integer i = 2;
int b = i;
2.自动装箱的过程其实可以起到节约内存的作用
Integer a =1;
Integer b =1;
Integer c =144;
Integer d =144;
System.out.println(a == b); //true
System.out.println(c == d); //false
自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象(享元模式)。而如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象
那么,为什么要这么设计呢?
一般来说,小数字的使用频率很高,将小数字保存起来,让其始终仅有一个对象可以节约内存,提高效率。
Integer自动装箱池的范围是-128~127
Byte,Short,Long范围是-128~127
Character范围是0~127
Float和Double没有自动装箱池
源码:看一下Integer.indexOf(int i)方法
public static Integer valueOf(int i)
{
if (i >= IntegerCache.low &&i <= IntegerCache.high)
return IntegerCache.cache[i +(-IntegerCache.low)];
return new Integer(i);
}
有兴趣的看下这个类IntegerCache
最后再补充一点
在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的, 在启动 jvm 的时候,通过 -XX:AutoBoxCacheMax= 来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。