1.包装类

有时候需要将 int 这样的基本类型转化为对象。所有的基本数据类型都有一个与之相对应的类。例如,Integer 类对应基本类型 int,这些类称为 包装器

  1. Integer
  2. Long
  3. Float
  4. Double
  5. Sort
  6. Byte
  7. Character
  8. Viod
  9. Boolean

对象包装器类是不可变的,一旦构造了包装器,就不允许更改包装在其中的值。同时包装器类还是final,因此不能定义他们的子类。
若想定义一个整型数组列表 ,而尖括号中的参数类型不允许为基本类型,这时候可以使用包装类。

  1. /* 错误的语法,尖括号中的参数不能使用int */
  2. ArrayList<int> list = new ArrayList()<>;
  3. /* 使用 int 的包装类 */
  4. ArrayList<Integer> list = new ArrayList()<>;

由于每个值包装在对象中,所以ArrayList<Integer> 的效率远低于 int[] 数组。因此,应该用它构建小型集合,其原因是此时程序员的操作方便性要比执行效率更重要。

2.自动装箱和拆箱

有一个很有用的特性,从而更加便于添加int类型元素到 ArrayList<Integer> 中。

  1. list.add(3);
  2. /* 将自动变化成 */
  3. list.add(Integer.valueOf(3))

这种变换称为自动装箱。相反的将一个Integer对现象赋值给一个int值时,将会自动的拆箱

  1. int n = list.get(i);
  2. /* 翻译为 */
  3. int n = list.get(i).inValue();
  1. 在算数表达式中也可以自动的拆箱和装箱。
  1. Integer n = 1;
  2. /* 编译器将自动的插入一条拆箱命令,然后进行自增计算,最后将结果装箱 */
  3. n++;

3.补充说明

  1. 由于包装器类引用可以为null,所以自动装箱时有可能会抛出一个 NullPointerException

    1. Integer n = null;
    2. System.out.println(n * 2); // Throws NullPointerException
  2. 如果在一个表达式中同时使用了 Integer 和 Double 类型,Integer值就会拆箱提升为 double ,在装箱为 Double。

    1. Integer n = 1;
    2. Double x = 2.0;
    3. System.out.println(true ? n : x); // Prints 1.0
  3. 拆箱和装箱是编译器认可的,而不是虚拟机。编译器再生成类的字节码文件时,插入必要的方法调用,虚拟机只是调用这些字节码。