原文: https://beginnersbook.com/2014/09/java-autoboxing-and-unboxing-with-examples/

Java 1.5 引入了一种特殊功能,即将原始类型自动转换为相应的包装器类,反之亦然。

自动装箱 :将原始类型自动转换为相应包装类的对象称为自动装箱。例如 - 将int转换为Integer,将long转换为Long,将double转换为Double等。

拆箱:这只是自动装箱的逆过程。自动将包装类的对象转换为其对应的原始类型类型称为拆箱。例如 - 将Integer转换为intLong转换为long,将Double转换为double等。

  1. Primitive type Wrapper class
  2. boolean Boolean
  3. byte Byte
  4. char Character
  5. float Float
  6. int Integer
  7. long Long
  8. short Short
  9. double Double

Java 中什么时候发生自动装箱和拆箱

自动装箱

让我们看一些带有示例的案例,其中发生了自动装箱。

案例 1 :当一个方法期望一个包装器类对象但是作为参数传递的值是一个基本类型。例如,在下面的代码中,方法myMethod()期望一个Integer包装类的对象,但是我们传递了一个原始的int类型。程序运行正常,因为编译器执行自动装箱(将int转换为Integer

  1. class AutoboxingExample1
  2. {
  3. public static void myMethod(Integer num){
  4. System.out.println(num);
  5. }
  6. public static void main(String[] args) {
  7. /* passed int (primitive type), it would be
  8. * converted to Integer object at Runtime
  9. */
  10. myMethod(2);
  11. }
  12. }

输出:

  1. 2

案例 2 :在某个时间点,您将原始类型值分配给其包装类的对象。例如:以下语句有效,因为编译器在运行时执行自动装箱。

  1. Integer inum = 3; //Assigning int to Integer: Autoboxing
  2. Long lnum = 32L; //Assigning long to Long: Autoboxing

案例 3 :处理集合框架类时:

  1. ArrayList<Integer> arrayList = new ArrayList<Integer>();
  2. arrayList.add(11); //Autoboxing - int primitive to Integer
  3. arrayList.add(22); //Autoboxing

这里ArrayList类需要一个Integer包装类对象,但是我们提供了int原始类型。

拆箱

案例 1 :方法期待Integer对象(参数)但我们提供了int。发生了将Integer转换为int的自动转换(拆箱)。

  1. class UnboxingExample1
  2. {
  3. public static void myMethod(int num){
  4. System.out.println(num);
  5. }
  6. public static void main(String[] args) {
  7. Integer inum = new Integer(100);
  8. /* passed Integer wrapper class object, it
  9. * would be converted to int primitive type
  10. * at Runtime
  11. */
  12. myMethod(inum);
  13. }
  14. }

输出:

  1. 100

案例 2 :作业

  1. Integer inum = new Integer(5);
  2. int num = inum; //unboxing object to primitive conversion

案例 3 :在处理集合类时:

  1. ArrayList arrayList = new ArrayList()
  2. int num = arrayList.get(0); // unboxing because get method returns an Integer object

幕后发生了什么?

在上一节中,我们学习了 java 编译器如何在基本类型和相应的包装器对象之间执行自动转换。让我们讨论一下编译器在自动装箱和拆箱过程中实际做了什么。理解这一点的最好方法是比较 java 1.5 之前和 java 1.5 之后的事情(java 1.5 中引入的装箱和拆箱)。

自动装箱

我们看到了什么:

  1. Integer number = 100;

编译器做了什么(或者我们以前在 java 1.5 之前做过的事情):

  1. Integer number = Integer.valueOf(100);

拆箱

我们看到了什么:

  1. Integer num2 = new Integer(50);
  2. int inum = num2;

编译器做什么:

  1. Integer num2 = new Integer(50);
  2. int inum = num2.intValue();

类似的事情发生在其他包装类和原始类型,如longdoubleshort等。

你应该注意的事情很少:

在进行比较时不要混合原始类型和对象。对于这样的比较,您可能会得到不可预测的结果。更好的做法是:将对象与对象进行比较(使用equals()方法)并将原始类型与原始类型进行比较(使用逻辑运算符,如==<等)。

参考

Javadoc - Autoboxing 和 Unboxing