从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。
  其他的也类似,比如Double、Character,不相信的朋友可以自己手动尝试一下。
  因此可以用一句话总结装箱和拆箱的实现过程:
  装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。
  三.面试中相关的问题
  虽然大多数人对装箱和拆箱的概念都清楚,但是在面试和笔试中遇到了与装箱和拆箱的问题却不一定会答得上来。下面列举一些常见的与装箱/拆箱有关的面试题。
  1.下面这段代码的输出结果是什么?

 

public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}

  也许有些朋友会说都会输出false,或者也有朋友会说都会输出true。但是事实上输出结果是:
  为什么会出现这样的结果?输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现:
  而其中IntegerCache类的实现为:
  从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
  上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。
  2.下面这段代码的输出结果是什么?

 

public class Main {
public static void main(String[] args) {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}

  也许有的朋友会认为跟上面一道题目的输出结果相同,但是事实上却不是。实际输出结果为:
  View Code
  至于具体为什么,读者可以去查看Double类的valueOf的实现。
  在这里只解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
  注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
  Double、Float的valueOf方法的实现是类似的。
  3.下面这段代码输出结果是什么:

 

public class Main {
public static void main(String[] args) {
Boolean i1 = false;
Boolean i2 = false;
Boolean i3 = true;
Boolean i4 = true;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}

  输出结果是:
  至于为什么是这个结果,同样地,看了Boolean类的源码也会一目了然。下面是Boolean的valueOf方法的具体实现:
  而其中的 TRUE 和FALSE又是什么呢?在Boolean中定义了2个静态成员属性:
  至此,大家应该明白了为何上面输出的结果都是true了。
  4.谈谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别。
  当然,这个题目属于比较宽泛类型的。但是要点一定要答上,我总结一下主要有以下这两点区别:
  1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;
  2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是的)。