# Java 包装器类 – 自动装箱，拆箱和转换示例

> 原文： [https://howtodoinjava.com/java/basics/java-wrapper-classes/](https://howtodoinjava.com/java/basics/java-wrapper-classes/)

了解 **Java 包装器类**的用法，它们在原始和对象之间的转换； 以及带有示例的自动装箱和拆箱。

## 1\. Java 包装器类

Java 提供**类型包装器**，它们是**封装对象内原始类型**的类。 在 Java 中，我们有 [8 种原始数据类型](https://howtodoinjava.com/java/basics/primitive-data-types-in-java/)。

包装器类将数据类型包装（封装）并赋予其对象外观。 在任何需要数据类型作为对象的地方，都可以使用此对象。 包装器类包括解包装对象并返回数据类型的方法。

*类型包装器*类是`java.lang`包的一部分。

每个基本类型都有一个对应的包装器类。

| **基本类型** | **包装类** |
| --- | --- |
| `double` | `Double` |
| `float` | `Float` |
| `long` | `Long` |
| `int` | `Integer` |
| `short` | `Short` |
| `byte` | `Byte` |
| `char` | `Character` |
| `boolean` | `Boolean` |

## 2\. 何时使用包装器类

在场景中使用 Java 包装器类：

*   当两个方法要引用基本类型的相同实例时，请将包装器类作为方法参数传递。
*   Java 中的泛型仅适用于对象，不支持原始类型。
*   Java 中的集合仅处理对象。 要将原始类型存储在这些类之一中，您需要将原始类型包装在一个类中。
*   要从数据类型引用`null`时，需要对象。 原始类型不能将`null`作为值。

## 3\. 转换

#### 3.1 包装器类的原始类型

有两种方法可以将原始类型转换为相应包装类的对象：

1.  使用**构造器**
2.  使用**静态工厂方法**（例如`valueOf()`）（字符除外）

```java
// 1\. using constructor
Integer object = new Integer(10);

// 2\. using static factory method
Integer anotherObject = Integer.valueOf(10);

```

在上面的示例中， `valueOf()`方法返回一个表示指定的`int`值的实例。

同样，我们可以将其他基本类型转换，例如将`boolean`转换为`Boolean`，将`char`转换为`Character`，将`short`转换为`Short`等。

> Java 包装器类使用[**内部缓存**](https://howtodoinjava.com/java/basics/object-initialization-best-practices-internal-caching-in-wrapper-classes/)，该缓存返回缓存的值，从而使其高效且在内存上明智。

#### 3.2 包装器类到原始类型

从包装器转换为原始类型很简单。 我们可以使用相应的方法来获取基本类型。 例如`intValue()`，`doubleValue()`，`shortValue()`等。

```java
Integer object = new Integer(10);

int val = object.intValue();	//wrapper to primitive

```

## 4\. 自动装箱和拆箱

从 JDK 5 开始，Java 添加了两个重要特性：*自动装箱*和*自动拆箱*。

#### 4.1 自动装箱

**自动装箱**是将原始类型自动转换为其对应的对象包装器类的方法。 例如，将`int`转换为`Integer`，将`char`转换为`Character`，依此类推。

我们可以简单地将原始类型传递或分配给接受包装类对象的参数或引用。 例如

```java
Character ch = 'a';		//char to Character

List<Integer> integerList = new ArrayList<>();

for (int i = 1; i < 10; i ++) 
{
    integerList.add(i);		//int to Integer
}

```

`integerList`是`Integer`对象的列表，而不是原始类型`int`值的列表。 编译器会根据`i`自动创建一个`Integer`对象，并将该对象添加到`integerList`中。 因此，前面的代码在运行时变成了下面的代码：

```java
List<Integer> integerList = new ArrayList<>();

for (int i = 1; i < 50; i += 2) 
{
    integerList.add(Integer.valueOf(i));		//autoboxing
}

```

#### 4.2 拆箱

**拆箱**是在从包装器类转换为其对应的原始类型时发生的。 这意味着我们可以将包装对象传递或分配给接受原始类型的参数或引用。 例如

```java
public static int sumOfEven(List<Integer> integerList) 
{
    int sum = 0;
    for (Integer i: integerList) {
    	if (i % 2 == 0)
            sum += i;			//Integer to int
    }
    return sum;
}

```

在上面的示例中，余数（`%`）和一元加（`+=`）运算符不适用于`Integer`对象。 编译器在运行时通过调用`intValue()`方法自动将`Integer`转换为`int`。

通过自动装箱和拆箱，开发人员可以编写**更干净的代码**，从而更易于阅读。

学习愉快！

阅读更多：

[SO 帖子](https://stackoverflow.com/questions/3579035/why-are-there-wrapper-classes-in-java)