装箱: 自动将基本数据类型转换为包装器类型 拆箱: 自动将包装器类型转换为基本数据类型
在JavaSE5之前,如果要生成一个数值为10的Integer对象,必须要这样写
Integer i = new Integer(10);
JavaSE5之后开始就提供了自动装箱的特性,只需要酱紫就可以了
Integer i=10;
所有的包装类型都是不变类,一旦创建,就是不变的
// Integer源码
public final class Integer {
private final int value;
}
| 基本类型 | 引用类型 |
|---|---|
| boolean | java.lang.Boolean |
| byte | java.lang.Byte |
| short | java.lang.Short |
| int | java.lang.Integer |
| long | java.lang.Long |
| float | java.lang.Float |
| double | java.lang.Double |
| char | java.lang.Character |
面试题:
public class Test{
public static void main(String[] args){
Integer a1=100;
Integer a2=100;
Integer a3=200;
Integer a4=200;
System.out.println(a1==a2) //true
System.out.println(a3==a4) //false
System.out.println(a3.equals(a4)); // true
}
}
为什么会出现这样的结果呢?输出的结果a1和a2指向的是同一个对象,而a3和a4指向的是不同的对象,看一下源码:
public static Integer valueOf(int i) {
//如果i的值大于-128小于127则返回一个缓冲区(常量池)中的已经初始化后Integer对象
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
}else{
return new Integer(i);
}
}
可以看出,在通过ValueOf()方法创建Integer对象的时候,如果数值在[-128,127]之间,返回指向IntegerCache.cache中已经存在的对象的引用,否则它就会创建一个新的Integer对象,上边代码中的a3和a4分别指向了两个不同的对象,所以不相等;
📝注意: 包装类必须使用equals去比较。== 操作比较的是两个变量的值,对于引用型变量是判断变量是否指向同一引用对象,比地址。equals 操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
总结
- 自动装箱和自动拆箱都是在编译期完成的(JDK>=1.5);
- 装箱和拆箱会影响执行效率,且拆箱时可能发生
NullPointerException; - 包装类型的比较必须使用
equals(); - 整数和浮点数的包装类型都继承自
Number;