1.包装类
有时候需要将 int 这样的基本类型转化为对象。所有的基本数据类型都有一个与之相对应的类。例如,Integer 类对应基本类型 int,这些类称为 包装器
- Integer
- Long
- Float
- Double
- Sort
- Byte
- Character
- Viod
- Boolean
对象包装器类是不可变的,一旦构造了包装器,就不允许更改包装在其中的值。同时包装器类还是final,因此不能定义他们的子类。
若想定义一个整型数组列表 ,而尖括号中的参数类型不允许为基本类型,这时候可以使用包装类。
/* 错误的语法,尖括号中的参数不能使用int */ArrayList<int> list = new ArrayList()<>;/* 使用 int 的包装类 */ArrayList<Integer> list = new ArrayList()<>;
由于每个值包装在对象中,所以ArrayList<Integer> 的效率远低于 int[] 数组。因此,应该用它构建小型集合,其原因是此时程序员的操作方便性要比执行效率更重要。
2.自动装箱和拆箱
有一个很有用的特性,从而更加便于添加int类型元素到 ArrayList<Integer> 中。
list.add(3);/* 将自动变化成 */list.add(Integer.valueOf(3))
这种变换称为自动装箱。相反的将一个Integer对现象赋值给一个int值时,将会自动的拆箱
int n = list.get(i);/* 翻译为 */int n = list.get(i).inValue();
在算数表达式中也可以自动的拆箱和装箱。
Integer n = 1;/* 编译器将自动的插入一条拆箱命令,然后进行自增计算,最后将结果装箱 */n++;
3.补充说明
由于包装器类引用可以为null,所以自动装箱时有可能会抛出一个 NullPointerException
Integer n = null;System.out.println(n * 2); // Throws NullPointerException
如果在一个表达式中同时使用了 Integer 和 Double 类型,Integer值就会拆箱提升为 double ,在装箱为 Double。
Integer n = 1;Double x = 2.0;System.out.println(true ? n : x); // Prints 1.0
拆箱和装箱是编译器认可的,而不是虚拟机。编译器再生成类的字节码文件时,插入必要的方法调用,虚拟机只是调用这些字节码。
