# Java 自动装箱和拆箱

> 原文： [https://beginnersbook.com/2014/09/java-autoboxing-and-unboxing-with-examples/](https://beginnersbook.com/2014/09/java-autoboxing-and-unboxing-with-examples/)

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

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

**拆箱**：这只是自动装箱的逆过程。自动将包装类的对象转换为其对应的原始类型类型称为拆箱。例如 - 将`Integer`转换为`int`，`Long`转换为`long`，将`Double`转换为`double`等。

```java
Primitive type	Wrapper class
boolean	        Boolean
byte	        Byte
char	        Character
float	        Float
int	        Integer
long	        Long
short	        Short
double	        Double
```

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

#### 自动装箱

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

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

```java
class AutoboxingExample1
{
   public static void myMethod(Integer num){
	System.out.println(num);
   }
   public static void main(String[] args) {
       /* passed int (primitive type), it would be 
        * converted to Integer object at Runtime
        */
   	myMethod(2);
   }
}
```

输出：

```java
2
```

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

```java
Integer inum = 3; //Assigning int to Integer: Autoboxing
Long lnum = 32L; //Assigning long to Long: Autoboxing
```

**案例 3** ：处理集合框架类时：

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

```

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

#### 拆箱

**案例 1** ：方法期待`Integer`对象（参数）但我们提供了`int`。发生了将`Integer`转换为`int`的自动转换（拆箱）。

```java
class UnboxingExample1
{
   public static void myMethod(int num){
	System.out.println(num);
   }
   public static void main(String[] args) {

    	Integer inum = new Integer(100);

        /* passed Integer wrapper class object, it 
         * would be converted to int primitive type 
         * at Runtime
         */
    	myMethod(inum);
    }
}
```

输出：

```java
100
```

**案例 2** ：作业

```java
Integer inum = new Integer(5);
int num = inum; //unboxing object to primitive conversion
```

**案例 3** ：在处理集合类时：

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

```

## 幕后发生了什么？

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

**自动装箱** ：

我们看到了什么：

```java
Integer number = 100;
```

编译器做了什么（或者我们以前在 java 1.5 之前做过的事情）：

```java
Integer number = Integer.valueOf(100);
```

**拆箱**：

我们看到了什么：

```java
Integer num2 = new Integer(50);
int inum = num2;
```

编译器做什么：

```java
Integer num2 = new Integer(50);
int inum = num2.intValue();
```

类似的事情发生在其他包装类和原始类型，如`long`，`double`，`short`等。

#### 你应该注意的事情很少：

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

#### 参考

[Javadoc - Autoboxing 和 Unboxing](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)