主题
面试速答(先看这里)
**一句话结论:**Java 中的 包装类缓存机制 ,主要是指 Java 对部分包装类(如 Integer , Byte , Short , Long , Character , Boolean )在 一定范围内的数值 使用了 缓存池 ,以提升性能、节省内存。
60秒标准回答:
这个问题其实考察的是 java中包装类的缓存机制 。先说答案
Java 中的 包装类缓存机制 ,主要是指 Java 对部分包装类(如 Integer , Byte , Short , Long , Character , Boolean )在 一定范围内的数值 使用了 缓存池 ,以提升性能、节省内存。 Java 对 以下包装类 中的 部分数值 进行了缓存
[-128, 127]
**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点
回答主线:
- **要点1:**这个问题其实考察的是 java中包装类的缓存机制 。
- **要点2:**注意: Float、Double不支持缓存。
- **要点3:**当我们在代码中写下 Integer a = 100; 的时候,实际上调用的是 Integer a = Integer.valueOf(127); (自动装箱)
- **要点4:**那么,可以看下Integer.valueOf的源码(以1.8为例):
- **要点5:**也就说,他会先判断这个 i 数字,是不是在 IntegerCache.low 和 IntegerCache.high 之间,如果是的话,则从IntegerCache中获取,否则在new一个新的。
**记忆锚点:**Integer → cache → Java → new → IntegervalueOf → IntegerCache
关键取舍:
- Java 中的 包装类缓存机制 ,主要是指 Java 对部分包装类(如 Integer , Byte , Short , Long , Character , Boolean )在 一定范围内的数值 使用了 缓存池 ,以提升性能、节省内存。
易错提醒:
- Java 对 以下包装类 中的 部分数值 进行了缓存: [-128, 127] [-128, 127] [-128, 127] [-128, 127] Character [0, 127] true , false 注意: Float、Double不支持缓存。
- 默认的缓存范围也 可以调整 ,可以通过 -Djava.lang.Integer.IntegerCache.high=200 的方式来设定上限,但是下限是不能调整的,这部分通过上面我贴的代码也能看得出来,就不展开说了。
加分表达:
- 这里的IntegerCache是个内部类,看一下前面用到的low、high和cache都是啥: 可以看到,low是-128,hign是127,也就意味着如果你要创建的一个数字,范围在-128到127之间(包含这两个数字本身),那么他就不会重复创建对象,而是从 Integer cache[] 这个整型数组中取出来。
- 当我们在代码中写下 Integer a = 100; 的时候,实际上调用的是 Integer a = Integer.valueOf(127); (自动装箱) 那么,可以看下Integer.valueOf的源码(以1.8为例): 也就说,他会先判断这个 i 数字,是不是在 IntegerCache.low 和 IntegerCache.high 之间,如果是…
追问准备:
- 围绕「Integer」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「cache」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「Java」:底层原理是什么?使用时有哪些边界和常见坑?
- 如果线上出现异常,你会如何定位、验证并规避?
典型回答
这个问题其实考察的是java中包装类的缓存机制。先说答案。
java
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false
Integer c = 100;
Integer d = 100;
System.out.println(c == d); // trueJava 中的包装类缓存机制,主要是指 Java 对部分包装类(如 Integer, Byte, Short, Long, Character, Boolean)在一定范围内的数值使用了缓存池,以提升性能、节省内存。 Java 对以下包装类中的部分数值进行了缓存:
| 包装类 | 缓存范围 |
|---|---|
Integer | [-128, 127] |
Short | [-128, 127] |
Byte | [-128, 127] |
Long | [-128, 127] |
Character | [0, 127] |
Boolean | true, false |
注意:Float、Double不支持缓存。我猜测可能是小数太多了,没办法穷举。
当我们在代码中写下Integer a = 100;的时候,实际上调用的是Integer a = Integer.valueOf(127);(自动装箱)
那么,可以看下Integer.valueOf的源码(以1.8为例):
java
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}也就说,他会先判断这个i数字,是不是在IntegerCache.low和IntegerCache.high之间,如果是的话,则从IntegerCache中获取,否则在new一个新的。
这里的IntegerCache是个内部类,看一下前面用到的low、high和cache都是啥:
java
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
//省略其余代码
}
}可以看到,low是-128,hign是127,也就意味着如果你要创建的一个数字,范围在-128到127之间(包含这两个数字本身),那么他就不会重复创建对象,而是从Integer cache[]这个整型数组中取出来。
(因为100在这个范围内,所以创建多次他都用的是同一个,而1000不在这个范围内,所以每次都会new一个,而==对比的是地址,所以new出来的对象的地址是不一样的,缓存中的地址就是同一个)
而这个Integer cache[]数组,会在刚开始就初始化好,代码如下:

同理,和Integer一样,其他的数据类型如Short、Boolean、Long等也有,范围在上面的表格中写了的。
默认的缓存范围也可以调整,可以通过-Djava.lang.Integer.IntegerCache.high=200的方式来设定上限,但是下限是不能调整的,这部分通过上面我贴的代码也能看得出来,就不展开说了。