首页 / JAVA  

详解Java的自动装箱与拆箱

简单一点说,装箱就是自动将基本数据类型转换为包装类型(包装类型是有一个对象可以调用方法);拆箱就是自动将包装类型转换为基本数据类型。

下面我们来看看需要装箱拆箱的类型有哪些:

 //自动装箱
  Integer total = 10;
  //自定拆箱
  int totalprim = total;
Integer total = 10; 
执行上面那句代码的时候,系统为我们执行了: 
Integer total = Integer.valueOf(10);
int totalprim = total; 
执行上面那句代码的时候,系统为我们执行了: 
int totalprim = total.intValue();


我们现在就以Integer为例,来分析一下它的源码: 

1、首先来看看Integer.valueOf函数

public static Integer valueOf(int i) {
return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}

上面的源码表示,数值在大于等于128这个区间或则是小于等于-128这个区间的数值,自动装箱时返回一个新的对象,否则会在SMALL_VALUES数组里得到同一个对象

下面代码:

Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);  //true
System.out.println(i3==i4);  //false

由于上面数据都是装箱类型,所以 == 比较的是对象,而不是数值;

又因为

100:不在 i >= 128 || i < -128  这个区间,所以它是在SMALL_VALUES数组里获取同一个对象

200:在 i >= 128 || i < -128  这个区间,自动装箱它会创建新的对象


Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2); //false
System.out.println(i3==i4); //false

对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的。 所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样。


下面我们进行一个归类: 

Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 

Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。


1.等号 == 两边有包装类和基本数据类型,会自动拆箱,所以比较的是值 

Integer num1 = 400;  
int num2 = 400;  
System.out.println(num1 == num2); //true

注:当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。


2019-10-21