Java 中的自动装箱和自动拆箱算是一种语法糖,也就是在编译阶段编译器在合适的状况下帮咱们的作了自动拆箱和自动装箱。html
众所周知,Java 中的基本数据类型并非对象,为了解决在必定切状况下咱们须要使用对象的时候,Java 为咱们提供了每一个基本类型对应的包装类,以下表:java
基本数据类型 | 数据类型包装类 |
---|---|
byte(1字节) | Byte |
short(2个字节) | Short |
int(4个字节) | Integer |
long(8个字节) | Long |
float(4个字节) | Float |
double(8个字节) | Double |
boolean | Boolean |
Integer i = 10; // 装箱 int num = i; // 拆箱
对于上面一段代码进行反编译能够获得:编程
0: bipush 10 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 5: astore_1 6: aload_1 7: invokevirtual #3 // Method java/lang/Integer.intValue:()I 10: istore_2 11: return
能够看出:装箱是Integer.valueOf() 方法,而拆箱是调用Integer.intValue() 方法,其余类型亦是如此。装箱时调用包装类的valueOf()方法,拆箱是调用包装类xxValue()方法。缓存
在下面的两种状况时,会发生自动装箱:oracle
对应以下代码:性能
// 基本类型做为参数传递到相应的包装类型方法 List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(i); // 基本类型分配到相应的包装类型变量 Integer i = 10;
在下面的两种状况时,会发生自动拆箱:学习
同时在进行 +,- 时,也会发生自动拆箱,由于 Integer 或其余包装类型对象没法使用运算符。因此编译时,若是包装类型使用运算符进行运算,会先进行自动拆箱再进行运算。.net
还有一种状况,就是在使用三目运算符的状况下,可能会发生自动拆箱。当返回的两个参数并非同一种数据类型时,编译器会进行自动拆箱,向下转型。只要一个运算中有不一样的类型,涉及到类型转换,那么编译器会往下(基本类型)转型,再进行运算,以下:指针
Double db1 = null; Long l2 = null; boolean flag =false; Double db2 = (flag) ? db1 : l2;
其中 db1 l2 不是同一种类型的参数,编译器会进行自动拆箱。
对应以下代码:code
// 包装类型做为参数传递给基本类型的方法 Integer i = new Integer(10); int i2 = getIntVal(i); private static int getIntVal(int i){ return i; } // 基本类型分配到相应的包装类型变量 int i = new Integer(10);
首先看下面一段代码:
Integer i1 = 10; Integer i2 = 10; Integer i3 = 200; Integer i4 = 200; System.out.println(i1 == i2); // true System.out.println(i3 == i4); // false
为何会产生上面的状况,前面提到,自动装箱调用的时valueOf() 方法,因此先看一下valueOf() 的源码:
public static Integer valueOf(int i) { // IntegerCache.low == -128 IntegerCache.high == 127 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
这段代码的意思时,每次调用Integer.valueOf() 方法时,若是在-128-127之间就会直接从缓存中取。这样作的缘由是,咱们在使用Integer 时大部分使用的数字都较小,这样能够提升效率,节省空间。
不单单是Integer,其余包装类有缓存:
只有double和float的自动装箱代码没有使用缓存,而double、float是浮点型的,没有特别的热的(常常使用到的)数据的,缓存效果没有其它几种类型使用效率高
虽然自动拆箱和自动装箱很方便,可是咱们在使用是须要注意自动拆装箱所带来的问题:
因此要建议避免无心中的装箱、拆箱行为