前言

Java为我们提供了八种基本的数据类型,每种类型都有其包装类,其中Integer是整型int的包装类,不知道大家有没有思考过,既然Java已经向我们提供了基本数据类型,又为什么还要为每个类型提供对应的包装类呢?

“Java中一切皆对象”这句话相信大家都不陌生,正如这句话所透露出来的信息,Java是一门面向对象的语言,但基本数据类型不属于对象,为了使基本数据类型拥有对象的性质和特征,我们需要将基本数据类型通过包装类封装起来,使得它具有对象的性质,并且为其添加属性和方法,丰富基本类型的操作。

Integer的自动拆装箱

在Java SE5中,为了减少开发人员的工作,Java提供了自动拆箱与自动装箱功能。

  • 自动装箱: 就是将基本数据类型自动转换成对应的包装类。
  • 自动拆箱:就是将包装类自动转换成对应的基本数据类型。 

下面的两行代码就是最经典的Integer的自动拆装箱示例,直接使用Integer a = 10即可完成对Integer的初始化,无需程序员自己实例化一个Integer(Integer a = new Integer(10))。同样的,当Integer要转化为int基本类型的数值时,我们程序员也无需自己去调用Integer内部的方法进行转换,这些操作Java都为我们去操作,不需要我们自己手动调用。

public static void main(String[] args) {
    Integer a = 10; // 自动装箱
    int b = a;      // 自动拆箱
}

Integer的自动拆装箱原理

为了探讨Integer的自动拆装箱原理,我们对上面的代码进行反编译查看程序具体的运行过程:

对上面代码进行反编译后,得到以下代码

public static void main(String[]args){
    Integer a  = Integer.valueOf(10); 
    int b = a.intValue(); 
}

不难看出,int的装配是通过Integer.valueOf()方法实现的,而Integer的自动拆箱都是通过integer.intValue来实现的。

首先来看看Integer中对于拆箱的具体源码:

java自动装箱是在什么时期完成的 integer自动装箱原理_Java

拆装的源码很简洁,与我们平时写的get()方法类似,使用名为value的成员变量保存Integer的值,后面通过intValue方法返回一个对应的基础数据类型int。

接下来看看装箱的源码:

java自动装箱是在什么时期完成的 integer自动装箱原理_包装类_02

可以看到,当Java对int类型的基础数据类型进行封装时,会先判断需要封装的值i是否大于IntegerCache.low,并且小于IntegerCache.high(low=-128,high=127)。这其实是Integer的一种缓存机制,Integer内部存在一个名为IntegerCache的静态内部类,针对int类型较多用到的范围-128~127的值进行缓存,Integer在封装这个范围内的值时会直接在缓存中取出对应的Integer对象,当封装超过这个范围的值时才会重新实例化一个Integer对象。

IntegerCache源码如下:

java自动装箱是在什么时期完成的 integer自动装箱原理_基本数据类型_03


总结

看到这里的您,应该已经对Integer的自动拆装原理有了一个大概的了解,不妨看看下面的代码,分析分析最终的输出结果会是多少?(关注公众号回复“integer”,即可得到该问题答案)

java自动装箱是在什么时期完成的 integer自动装箱原理_Java_04