一.装箱封箱的概念
装箱:基本数据类型转换为对应的包装类类型。
拆箱:包装类类型转换为对应的基本数据类型。

基本数据类型与其对应的包装类:
byte/short/char/int/long/double/float/boolean
Byte/Short/Character/Integer/Long/Double/Float/Boolean

装箱过程实际上调用对应类.valueOf()方法实现
拆箱过程实际上调用的是对应类.intValue()方法实现

例:int装箱过程实际上调用Integer.valueOf()方法实现,Integer拆箱过程实际上调用的是Integer.intValue()方法实现

包装类的用途:
把基本类型变成对象类型,包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

装箱拆箱的使用举例:

public static void main(String[] args) {
    Integer i = 1; //自动装箱
    //等价于 Integer i = new Integer(1);
    int n = i;//自动拆箱
    //等价于 int n = 1;
}

拆箱装箱例题:
例1:

Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 300;
Integer i4 = 300;

System.out.println(i1 == i2);//true
System.out.println(i3 == i4);//false
System.out.println(i1.equals(i2));//true
System.out.println(i3.equals(i4));//false
//求输出结果

首先包装类中会存储一个High值和一个Low值,Java的包装类中有一个数组是由这两个值及其之间的所有数组成的一个缓存数组,这个数组称为缓冲区,只要在这两个值之间的数字需要被封箱到包装类时,直接返回缓存区中值就可以,而缓存数组中的值是只有一份的,所以指向缓存数组的值的引用之间也都是相同的。
Integer类中的High值是127,Low值是-128,也就是说在这两个值之间的所有数封箱时都是指向缓存数组的,故i1==i2为真;而i3,i4的值超出了这个范围,那么i3和i4就是指向通过new操作符创建的对象的引用,故不相同。
而Boolean类中的true和false这两种结果都是已经缓存好的。
例2:

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3l;
Long h = 2l;

System.out.println(c == d);//true
System.out.println(e == f);//false
System.out.println(c == (a+b));//true
System.out.println(c.equals(a+b));//true
System.out.println(g == (a+b));//true,因为Java中小类型会自动转化为大类型
System.out.println(g.equals(a+b));//false,因为类型上根本就不匹配,Long和Integer
System.out.println(g.equals(a+h));//true,小类型与大类型运算时发生了自动转换。

需要注意的是,在Java中包装类和基本类型一样也是具有小类型自动转换为大类型这个特性的,而且比较包装类的时候首先要注意是否是同一个包装类。

System.out.println(c == (a+b));//true


为何1和2的引用相加会变成3的引用?
解析:包装类做运算时会拆箱将其转变为基本类型去运算,然后在比较的时候再进行一次自动的装箱比较引用。而实际上最后比较的就是3和3的引用,3在Integer类的缓冲区中故为true。