Java中集合只允许存储引用数据类型,那么 int char double等基础数据类型,如何存储在集合里呢?Java在JDK1.5版本以后推出了自动装箱、自动拆箱操作,那么什么是自动装箱呢,下面我们举两个例子看:
手动装箱示例: 先声明基础数据类型 int,再声明包装类 Integer 把int包装到Integer 再往list集合中add
int x = 90; //声明基础数据类型变量
Integer integer = new Integer(x); //声明Integer包装类 把int类型的x变量包装到Integer中
ArrayList list = new Arraylist; //创建ArrayList集合
list.add(integer); //将Integer包装类添加到list集合中(这种手动把int装到list里的操作,是比较麻烦的 所以后面推出了 自动装箱)
System.out.print(list); //输出list集合对象(也可以写成 list.toString(),输出的原理是调用了重写的toString方法)
自动装箱示例:
int i = 99; //声明基础数据类型int变量
ArrayList list = new ArrayList();
list.add(i); //触发自动装箱,int类型自动转换成 Integer
System.out.println(list);
如上所示就是集合中的自动装箱,将基础数据类型 装箱成了包装类;
自动装箱:就是将基础数据类型 自动转化为包装类;
byte ->Byte
char ->Character
short ->Short
int ->Integer
long ->Long
float ->Float
double ->Double
boolean->Boolean
那么什么叫自动拆箱呢?再接着看两个例子
public class Main{
public static void main(String[] args){
Integer int1 = 50;
Integer int2 = 50;
Integer int3 = 500;
Integer int4 = 500;
System.out.println(int1 == int2);
System.out.println(int3 == int4);
}
}
以上代码 输出的结果 : 第一行为 true 第二行为 false。
那么同样是 == ,为什么会出现这种情况呢?
首先,“ == ” 与 .equals()方法的区别我们需要知道, 通常情况下"==" 比较的是两个对象的地址值是否相同,.equals()方法则是比较 值本身 是否相同。
我们进入Integer类进行查看,发现编译器最终会调用传int参数的ValueOf方法
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
//.........
//其中代码不做描述,如想看详细 可以自行查阅源码
}
}
简单描述,IntegerCache把-128到 127之间的数 ,定义成了常量。
那这段代码的意思为,如果值在-128到127之间 则返回这个常量值,如果在-128-127之外,则new Integer 新创建一个Integer类型的对象出来。
因此可以得出 int1 == int2 为true ,因为是常量间的比较(常量是不可变的,在代码运行初即执行,静态方法 常量 都会被初始化到静态方法区,不在堆、栈中体现)
而 int3 == int4 为false ,因为不在-128到127之间,所以是新new的Integer对象,此处 “== ” 为判断地址值是否相等,故结果为 false。
接下来做一段练习
public static void main(String[] args){
Integer int1 = 3;
Integer int2 = 3;
Integer int3 = 6;
int int4 = 20;
int int5 = 20;
Integer integer6 = new Integer(20);
Integer integer7 = new Integer(20);
Integer integer8 = new Integer(3);
System.out.println(int3 == (int1 + int2));//true
System.out.println(int3.equals(int1+int2));//true
System.out.println(int4 == int5);//true
System.out.println(integer6 == int4);//true
System.out.println(integer6 == integer7);//false
System.out.println(integer8 == int1);//false
}
可以看到最后两行输出结果为 false
第4行 Integer6 == int4,编译器自动调用了 自动拆箱,把Integer6 拆成了int 类型去比较,因此比较的是值,返回 true
第5行 integer6 == integer7 为false,是因为== 比较的是 地址值,而 integer6 和integer7 都是新 new的对象,地址值肯定不同,所以为 false
第6行 integer8 == int1 为false,同理 integer8 为new的对象 int1为一个常量 ,地址值也是不同,所以为false。
以上就是自动装箱 与 自动拆箱的简单解析了。
如有错误请留言纠正 ,谢谢!