我们知道Java中所有的类都继承Object
类,那也就是说,Object
引用可以指向任意类型的对象,但是这时会出现一个问题,8种基本的数据类型不是对象。
为了解决这个问题,java中引入了一个特殊类,就是这8中基本类型的包装类。
对象的包装器类是不可变的,一旦进行了包装,就不允许更改包装在其中的值,与此同时,对象包装类还是final
,因此不能有他们的子类
装箱和拆箱
int i = 1;
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer i1 = Integer.valueOf(i);
Integer i2 = new Integer(i);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = i1.intValue();
public class TestDemo {
public static void main(String[] args) {
int n = 1;
Integer l1 = n;//自动装箱
int m = l1;//自动拆箱
}
}
将如上代码反编译,我们可以看到,自己调用了valueOf,intValue
方法,同时我们注意的是:自动装箱和自动拆箱是工作在编译期间的一种机制
- 在算数表达式中其实也可以自动进行装箱,拆箱
Integer n = 3;
n++;
反编译一下,我们很清楚的看到装箱,拆箱过程。编译器将自动的插入一条对象拆箱操作,然后是自增计算,最后在进行装箱
注意:
-
自动装箱规范要求boolean,byte,char <=127,在-128 ~127之间的short,int类型被包装- 固定的对象中。
我们通过例子来看这个问题//false对象都是创建在堆中的,地址是不同的 Integer i = new Integer(1); Integer j= new Integer(1); System.out.println(i==j); //true //java在编译Integer o1 = 1时,会翻译成Integer o1 = Integer.valueOf(1),也就是装箱 Integer o1 = 1; Integer o2 = 1; System.out.println(o1==o2); //false(Integer类型范围值-128 ~127 ,如果超过这个区间,就会创建新的对象) Integer o3 = 128; Integer o4 = 128; System.out.println(o3==o4); //false Integer i1= 127; Integer j1= new Integer(127);//在堆中创建的对象 System.out.println(i1==j1); //true // 包装类Integer变量在与基本数据类型int变量比较时,Integer会自动拆包装为int, // 然后进行比较,实际上就是两个int变量进行比较 Integer i5 = 127; int j5 = 127; System.out.println(i5==j5); // true // 包装类Integer变量在与基本数据类型int变量比较时,Integer会自动拆包装为int, // 然后进行比较,实际上就是两个int变量进行比较 Integer i2 = 128; int j2 = 128; System.out.println(i2 == j2);
-
如果在一个表达式子中,混合使用Integer和Double类型,Integer会自动拆箱,提升为double,在进行装箱
Integer n = 1; Double x = 2.0; System.out.println(true ? n : x); // Prints 1.0
-
包装类引用可以
null
,所以自动装箱有可能抛出一个NullPointerException
异常Integer n = null; System.out.print(4*n); // Throws NullPointerException