Java:基本类型与包装类(Integer)
·
一、前置知识点
1. 基本类型与包装类整体介绍
Java 有 8 种基本数据类型,为了让基本类型具备对象特性、可以赋值为 null、支持泛型、参与集合存储,每种基本类型都对应一个包装类:
| 基本类型 | 对应包装类 | 占用字节 | 取值范围 |
|---|---|---|---|
| byte | Byte | 1 字节 | -128 ~ 127 |
| short | Short | 2 字节 | -32768 ~ 32767 |
| int | Integer | 4 字节 | -2147483648 ~ 2147483647 |
| long | Long | 8 字节 | 很大 |
| float | Float | 4 字节 | 小数 |
| double | Double | 8 字节 | 小数 |
| char | Character | 2 字节 | 0 ~ 65535 |
| boolean | Boolean | 未定 | true / false |
核心区别总览
- 基本类型:不是对象,直接存数值,在栈内存,默认有初始值。
- 包装类:引用类型、对象,存堆内存,变量存对象地址,可以为
null,具备方法和属性。
2. 内存存储本质差异
基本类型 int
int a = 10;
- 直接在栈内存开辟空间,直接存放数值 10
- 没有对象、没有地址,只存值
包装类 Integer
Integer a1 = 10;
Integer a2 = new Integer(10);
- 栈中存对象地址
- 真实数值存在堆内存的对象里
- 可以赋值为
Integer x = null;,基本类型不能为 null
3. 自动装箱与自动拆箱(编译期自动优化)
自动装箱
定义:基本类型 自动转为 包装类对象写法:
Integer num = 10;
编译器底层自动补全:
Integer num = Integer.valueOf(10);
自动拆箱
定义:包装类对象 自动转为 基本类型数值场景:包装类和基本类型运算、比较、赋值
int n = num;
boolean flag = num == 10;
编译器底层自动补全:
int n = num.intValue();
boolean flag = num.intValue() == 10;
总结:装箱用 valueOf(),拆箱用 intValue(),都是编译器自动完成。
4. IntegerCache 整数缓存池(必考核心)
底层原理
Integer 内部有私有静态内部类 IntegerCache,提前预创建、缓存一批 Integer 对象。
- 默认缓存范围:-128 ~ 127
- 只要在这个范围,用
Integer 变量 = 数值方式创建,复用缓存中同一个对象,地址完全一样。
两种创建方式区别
Integer a = 10;底层调用Integer.valueOf(10)→ 走缓存,复用对象。new Integer(10)直接在堆中新建对象,永远不走缓存,哪怕数值在 -128~127 也是全新对象。
缓存可修改(拓展知识点)
可以通过 JVM 启动参数调整缓存上限:
-XX:AutoBoxCacheMax=200
可以把缓存上限改成 200,-128~200 之间都复用缓存。
5. == 与 equals () 完整区分规则
| 比较场景 | == 规则 | equals () 规则 |
|---|---|---|
| int 与 int | 直接比较数值 | 无,基本类型没有方法 |
| Integer 与 Integer | 比较内存地址 | Integer 重写了方法,只比较内部数值 |
| Integer 与 int | 包装类自动拆箱,比数值 | 基本类型自动装箱,比数值 |
核心口诀:
- 基本类型 == 只比值
- 包装对象 == 比地址
- 包装对象等值比较只用 equals
6. 包装类特有特性(补充拓展)
- 包装类可以为 null
Integer x = null; // 合法
int y = null; // 编译报错
开发中接收前端参数、数据库字段,必须用包装类,允许为空。
- 支持泛型、集合存储集合只能存引用类型,不能存基本类型:
List<Integer> list = new ArrayList<>(); // 合法
List<int> list = new ArrayList<>(); // 编译报错
- 提供大量工具常量 / 方法
Integer.MAX_VALUE; // int最大值
Integer.MIN_VALUE; // int最小值
Integer.parseInt("123"); // 字符串转int
Integer.toString(100); // 数值转字符串
二、经典例题插入 + 逐行精讲
原题代码
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 10;
Integer a1 = 10;
Integer b1 = 10;
Integer a2 = new Integer(10);
Integer b2 = new Integer(10);
System.out.println(a == b); // true
System.out.println(a1 == b1); // true
System.out.println(a2 == b2); // false
System.out.println(a1 == a); // true
System.out.println(a1.equals(a)); // true
System.out.println(a1 == a2); // false
System.out.println(a == a2); // true
}
}
内存结构文字图解
栈内存:
a、b:直接存数值 10
a1、b1:同时指向 IntegerCache 缓存中同一个对象
a2、b2:分别指向堆中两个不同的 new Integer 对象
堆内存:
缓存池:唯一一个数值为10的Integer对象
new 对象1:a2 指向
new 对象2:b2 指向
逐行结果 + 详细原理
| 代码 | 结果 | 详细解释 |
|---|---|---|
| a == b | true | 两个 int 基本类型,== 直接比较数值 10=10 |
| a1 == b1 | true | 自动装箱,数值 10 在 - 128~127,复用缓存同一个对象,地址相同 |
| a2 == b2 | false | 两个 new Integer,堆中两个独立对象,地址不一样 |
| a1 == a | true | Integer 和 int 比较,自动拆箱,转成 int 比数值 |
| a1.equals(a) | true | equals 重写只比数值,a 自动装箱为 Integer 再比较 |
| a1 == a2 | false | a1 是缓存对象,a2 是 new 新对象,地址不同 |
| a == a2 | true | a2 自动拆箱为 int,和 a 比数值 |
三、高频易错陷阱
陷阱 1:超出缓存范围直接为 false
Integer x = 128;
Integer y = 128;
System.out.println(x == y); // false
原因:128 超出默认缓存 -128~127,不再复用缓存,创建两个不同对象。
陷阱 2:new 对象永远不走缓存
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y); // false
无论数值是否在缓存区间,只要 new,一定是新对象。
陷阱 3:包装类为 null 触发空指针
Integer x = null;
int y = x; // 运行空指针异常:拆箱时调用intValue()
开发中包装类转基本类型一定要判空。
陷阱 4:不要用 == 判断包装类数值相等
业务开发、数据库比较、接口参数:一律使用 equals (),杜绝用 ==。
四、完整版终极背诵总结
- 基本类型存栈、存数值;包装类是对象,栈存地址、堆存数值。
- 自动装箱底层
valueOf(),自动拆箱底层intValue()。 - Integer 默认缓存范围 -128~127,范围内常量赋值复用同一对象。
new Integer()永远新建对象,不使用缓存。- 基本类型
==比数值;包装类==比地址,equals()比数值。 - 包装类和基本类型比较,自动拆箱只比数值。
- 包装类可以为 null、支持泛型集合、拥有工具方法;基本类型不行。
- 开发中 Integer 数值是否相等,强制用 equals ()。
更多推荐


所有评论(0)