一、自动装箱
假设想定义一个整形数组列表。而尖括号中的类型参数不允许是基本类型,也就是说,不允许写成ArrayList<int>。这里就用到了Integer对象包装器类。我们可以声明一个Integer对象的数组列表。
ArrayList<Integer> list = new ArrayList<>();
幸运的是,有一个很有用的特性,从而更加便于添加int类型的元素到ArrayList<Integer>中。下面这个调用
list.add(3);
将自动换成
list.add(Integer.valueOf(3));
这种变换就叫做自动装箱(autoBoxing)。
二、自动拆箱
相反的,当将一个Integer对象赋给一个int值的时候,将会自动拆箱。也就是说,编译器将下列语句:
int n = list.get(i);
翻译成:
int n = list.get(i).intValue();
甚至在算数表达式中也能够自动的装箱和自动的拆箱。例如,可以将自增操作应用于一个包装器引用:
Integer n = 1000;
n++;
编译器将自动的插入一条对象拆箱的指令,然后进行自增计算,最后再将结果装箱。
三、假象
大多数情况下,容易有一种假象,即基本类型与他们的对象包装器是一样的,只是他们的相等性不同。大家知道,==运算符也可以应用于对象包装器对象,只不过检测的是对象是否指向同一块存储区域,因此,下面的比较通常不会成立:
Integer a = 1000;
Integer b = 1000;
if(a == b) {
System.out.println("相等");
}
//不会输出“相等”
然而java实现确实有可能让它实现。如果将经常出现的值包装在同一个对象中,对这种比较就会成立。这种不确定的结果并不是我们所希望的。解决这个问题的办法就是在对两个包装器对象比较时,调用equals方法。
举个假象的例子:
Integer a = 127;
Integer b = 127;
if(a == b) {
System.out.println("相等");
}
//会输出“相等”
警告:
自动装箱规范要求,boolean、byte、char<=127, -128<= short、int <=127被包装到固定的对象中。也就是说:刚才a和b都等于127,介于-128~127之间,所以他俩其实指向的是同一个对象,所以用==比较的话,肯定是true。