# 有了基本数据类型，为什么还需要包装类型

在java中有八种基本数据类型对应每种基本类型又有八种包装类型：

基本类型：boolean， char， int， byte，short，long， float，double

包装器类型：Boolean，Character，Integer，Byte，Short，Long，Float，Double

从上面我们可以看到除了 char和int其它的包装类型名称和对应的基本类型一样只是首字母大写了。

既然有了基本类型为什么还要有包装类呢？我们在使用的过程中究竟用基本类型还是包装类呢？

在某些场合不能使用基本类型必须使用包装类，比如集合能接收的类型为Object,基本类型是无法添加进去的，还有范型也必须使用包装类。

另外假设我们要定义一个变量表示分数 如果用基本类型表示的话：int score;

默认值为零，如果我想表示分数为空也就是没有参加考试就没法表现了因为值类型是无法赋空值的，如果使用包装类型Integer score,就可以表示这种情况，因为Integer的默认值为空。

包装类型是引用类型，说白了就是一个类，既然是类，里面可以有属性和方法，它里面有哪些属性和方法呢？每个包装类型和基本数据类型都是大同小异的，我们拿Integer 和 int来举例说明：

假设有这样一个场景，我接收到一个String型的数据想把它转换为整型，如果没有包装类这个操作是无法完成的，有了包装类我们可以这样做：

```java
String num1 = "123";
int num2 = Integer.parseInt(num1);
```

parseInt就是Integer包装类提供的一个将字符串转成int型的方法。

包装类还有一个很重要的特新就是数据缓存：

还是拿Integer来举例，在-128~~127区间的数会被缓存，当类加载的时候就创建这256个数对应的对象，并放到名为cache的数组中，调用valueOf()方法时会先判断该数是否在-128~~127的区间，如果在则直接获取数组中该对象的引用，如果不在则创建该对象。valueOf()方法的源码如下:

**public static** Integer valueOf(**int** i) {**if** (i >= IntegerCache.\***low\*** && i <= IntegerCache.\***high\***)**return** IntegerCache.\***cache\***\[i + (-IntegerCache.\***low\***)];**return new** Integer(i);\
}

这里IntegerCache.low为-128，IntegeCache.high为127,IntegerCache.cache为数组存储的就是-128到127的Integer对象。

在自动装箱的时候调用的就是valueOf方法。

我们来看下面这段代码：

```java
public static void main(String[] args) {
Integer num1 = 4;
Integer num2 = 4;
System.out.println(num1==num2);
System.out.println(num1.equals(num2));
Integer num3 = 145;
Integer num4 = 145;
System.out.println(num3==num4);
System.out.println(num3.equals(num4));
}
```

```java
运行结果

true

true

false

true
```

为什么会是这个结果呢？

Integer num1 = 4，这里发生了自动装箱，调用了ValueOf()方法，因为4在-128\~127之间所以num1和num2都指向了缓存中的同一地址，所以用==比较和equls比较返回的都是true.

Integer num3 = 145，因为145不在这个范围区间，所以会在堆中生成对象num3和num4分别指向两个不同地址的对象，所以===返回false。从这个例子我们可以看出，如果要进行比较最好使用equals,如果使用==在数值范围不同的情况下得到的结果也是不同的。

各包装类缓存的取值范围：

· Boolean：使用静态 final 定义；

· Byte：缓存区 -128\~127

· Short：缓存区 -128\~127；

· Character：缓存区 0\~127；

· Long：缓存区 -128\~127；

· Integer：缓存区 -128\~127。

Float 和 Double 不会有缓存。

那么具体什么时候使用基本数据类型什么时候使用包装类呢?

有一个典型的场景，比如在控制器中接收一个参数该参数定义成了基本数据类型int那么传过来的参数如果为空则会报空指针错误，如果定义为其包装类型Integer则不会报错，而是得到一个null值。所以在RPC方法里面参数和返回值类型都需要用包装类。

我们再来看一个情况：Pojo类中如果定义成基本类型，数据库中对应的字段为空的时候映射时会出问题。因为基本类型不能赋null。所以在Pojo类中数据类型都需要定义成包装类。

如果是局部变量我们一般定义成基本类型，因为基本类型存储在栈上，方法执行完毕，栈上的内存空间也随之释放。

**总结一下：**

**为什么会有包装类？**

**1. 包装类里面有一些很有用的方法和属性，如HashCode,ParseInt**

**2. 基本类型不能赋null值，某些场合需要。**

**3. 有些地方不能直接用基本类型，比如集合**

**什么时候用包装类，什么时候用基本类型？**

**1. 在pojo类中定义的属性用包装类**

**2. 在rpc方法中定义参数和返回值的类型用包装类**

**3. 定义局部变量用基本类型**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://qiangrens-organization.gitbook.io/qkd90/java-kai-fa/you-le-ji-ben-shu-ju-lei-xing-wei-shen-me-hai-xu-yao-bao-zhuang-lei-xing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
