一.装箱和拆箱
在java中所有的类都是对象,但是有八种基本数据类型是例外.这八种基本数据类型 byte ,short,int,long,char,float,double,boolean 都不具备对象的特性,即不携带属性,没有方法可以调用.为了解决这个问题,javaJava为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes).
基本数据类型对应的包装类
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
每个包装类的对象可以封装一个相应的基本类型的数据,并提供了其它一些有用的方法。而包装类对象一经创建,其属性是无法改变的,要想改变其内容,只能重新创建对象.
而其中
将基本数据类型转换为对应的包装类的过程叫装箱,
将包装类转换为对应的基本数据类型的过程叫拆箱.
自动装箱和自动拆箱
在Java1.5之前,如果要创建数值为1的Integer对象必须这样写:Integer i = new Integer(1);
而且int类型数据与Integer类型数据不能互相赋值.
//在Java1.5之前是不允许这样做的
Integer i = 5;
两种数据之间不能相互赋值,这样导致了我们在使用过程中会有许多不方便的地方.所以在Java1.5之后,Java为我们提供了自动装箱和自动拆箱的功能.
//Java自动将int类型的''1''装箱为Integer对象
Integer i = 1;
//Java自动将Integer类型的i拆箱为int
int j = i;
装箱和拆箱是如何实现的?
在Integer源码中可以找到两个方法:static Integer valueOf(int i) 和 int intValue();从中我们可以清晰的看出装箱和拆箱是如何实现的.
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的.
装箱和拆箱的一些细节
Integer a = 1;
Integer b = 1;
Integer c = 150;
Integer d = 150;
System.out.println(a==b);
System.out.println(c==d);
类比于String类型,可能很多人都认为输出的答案都为true,但实际上答案是
true
false
为什么会这样,其实看一下valueOf的代码就知道了:
//low = -128 hight = 127
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看出,当int的值在[-128,127]之间的时候,valueOf会返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象.
那么是不是所有的包装类型都会将数值相同的对象指向同一个内存空间吗?
事实上,只有Integer、Short、Byte、Character、Long这几个类的valueOf才会如此.
而Double、Float的valueOf则会为每个对象分配不同的内存空间
Double a= 1.0;
Double b = 1.0;
System.out.println(a==b);
很明显,这段代码的输出结果为false