为什么Java中“1000==1000”为false,而”100==100“为true?
在日常编程中,我们经常遇到一些看似简单却隐藏着复杂逻辑的问题。
比如,你是否想过为什么在 Java 中表达式1000==1000会返回 false,而 100==100 却返回 true 呢?
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // 输出:true
Integer c = 1000;
Integer d = 1000;
System.out.println(c == d); // 输出:false
1、源码追溯
解决问题,一定要深入本质,而解决编程问题,深入本质的方法就是对源码一探究竟。
可能大家不知道 Integer a = 100 这种代码是看哪个源码,不要紧,我们可以看下其编译后的 class 文件。

很明显,我们得看 Integer 类的 valueOf 方法:

继续看 IntegerCache :

为了防止大家不好理解,我这里为这个方法添加了详细注释:
private static class IntegerCache {
// 缓存的下界值,固定为-128
static final int low = -128;
// 缓存的上界值,可以通过系统属性进行配置
static final int high;
// 缓存数组,用于存储从low到high范围内的Integer对象
static final Integer cache[];
static {
// 默认情况下,缓存的上界是127
int h = 127;
// 尝试从系统属性java.lang.Integer.IntegerCache.high中获取自定义的上界值
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
// 将字符串转换为整数
int i = parseInt(integerCacheHighPropValue);
// 确保自定义的上界至少为127,以包含Java规范要求的缓存范围
i = Math.max(i, 127);
// 确保上界不超过Integer.MAX_VALUE - (-low) - 1,以防止数组大小超出Integer的最大值
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// 如果字符串无法解析为整数,忽略该属性并保持默认的上界值
}
}
// 设置高界值
high = h;
// 初始化缓存数组,数组大小根据low和high计算得出
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++) {
// 创建Integer对象并填充数组
cache[k] = new Integer(j++);
}
// 断言确保缓存的上界至少为127,符合Java语言规范
assert IntegerCache.high >= 127;
}
// 私有构造器,防止外部实例化这个内部类
private IntegerCache() {}
}
2、源码解读
其实这部分源码不难理解,首先对于 valueOf 方法,当传入的整型值在 -128-127 之间时,返回的是 IntegerCache 里面的值。
这个 IntegerCache 是在 Java 的 Integer 类中的一个内部静态类 ,它缓存了 -128 到 127 之间的整数。
当我们声明一个 Integer 对象并赋予一个在这个范围内的值时,Java 实际上会返回一个预先创建好的对象引用。
这种机制可以有效减少内存的使用,并提高性能。
3、解答问题
看懂了源码,在回到上面的问题,为什么表达式1000==1000会返回 false,而 100==100 却返回 true 呢?
当我们使用 Integer 对象比较两个数时,实际上是在比较对象的内存地址。由于“100”在缓存范围内,两个“100”实际上引用的是同一个对象,所以返回 true。
相反,“1000”不在缓存范围内,即使数值相同,两个“1000”也是不同的对象,因此内存地址不同,返回 false。
4、正确比较
其实对于 Integer 这种包装类比较大小,我们应该使用 equals() 方法来比较两个 Integer 对象的数值,而不是直接使用 == 操作符,除非我们确实想比较对象的引用。
Integer a = 100;
Integer b = 100;
System.out.println(a.equals(b)); // 输出:true
Integer c = 1000;
Integer d = 1000;
System.out.println(c.equals(d)); // 输出:true
这点在阿里开发手册中也有详细说明:

如果你是一名Java开发人员,我还是比较推荐你去阅读这个手册,对我们日常编码规范还是挺有帮助的。
下载链接:https://pan.quark.cn/s/30d2c2c4239a

为什么Java中“1000==1000”为false,而”100==100“为true?的更多相关文章
- 为什么在 Java 中128==128返回false,而127==127返回true呢?
为什么在 Java 中128==128返回false,而127==127返回true呢? 有这样一段代码 Integer a=127; Integer b=127; System.out.printl ...
- jvm常量池 vsv为什么1000 == 1000返回为False,而100 == 100会返回为True?
在jvm规范中,每个类型都有自己的常量池.常量池是某类型所用常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型.字段.方法的符号引用.之所以是符号引用而不是像c语言那样,编译时直接 ...
- js中的0就是false,非0就是true及案例
在处理js代码判断真假时经常会这么写. 但fun()可能得到的是数字0,这可不是表示的没有值,但是!js中的数字0就是false,非0就是true. 于是0就被无情的当做false了. 已经被这个坑过 ...
- js中的0就是false,非0就是true。
在处理js代码判断真假时经常会这么写. var vale = fun();//从某个地方获取的值. if(!value){ 进入这里表示value为false或不存在 }但fun()可能得到的是数字0 ...
- 奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?
如果你运行如下代码: 1 2 3 4 Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = ...
- java中从1000万个随机数中查找出相同的10万个随机数花的最少时间
偶然在群里看到有人问到大数据查询,自己也就想了小艾改如何解决,从从1000万个随机数中查找出相同的10万个随机数花的最少时间, 谈到效率,自然是hashmap莫属. import java.util. ...
- java 中 sleep(1000) 和 wait(1000) 的区别?
1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使 ...
- 053、Java中使用for循环实现1~100的累加
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 051、Java中使用while循环实现1~100的累加
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- java 中的& &&区别以及 C++ 中& &&的区别
java中的 & &&两个运算符 (1).&在java中称做: 逻辑与 判断boolean类型,只有两者都是true时,才会返回true 举例: boolean b1= ...
随机推荐
- centos7安装Python3.7,执行./configure时报错,configure: error: no acceptable C compiler found in $PATH
执行./configure时报错,configure: error: no acceptable C compiler found in $PATH 在安装python3.7,配置编译路径时会遇到以下 ...
- 洛谷题解 | P1051 谁拿了最多奖学金
目录 题目描述 输入格式 输出格式 输入输出样例 提示 题目思路 AC代码 题目描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1. 院士奖学金,每人 ...
- vue上通过krpano.js实现360全景图
首先贴出一些XML对应的函数,文件内容都有注释说明, 前端代码读取xml文件代码 // 初始化 window.embedpano({ xml: 0, target: 'pano', html5: 'o ...
- 文本编辑器vi使用命令
使用对象: 用于编辑任何ASCII文本,对于编辑源程序尤其有用.可以对文本进行创建]查找.替换.删除.复制和粘贴等操作. 三种工作模式 命令模式:进入vi编辑器默认处于命令模式.命令模式下控制屏幕光标 ...
- 基于ZXing.NET实现的二维码生成和识别客户端
一.前言 ZXing.Net的一个可移植软件包,是一个开源的.多格式的1D/2D条形码图像处理库,最初是用Java实现的.已经过大量优化和改进,它已经被手动移植.它与.Net 2.0..Net 3.5 ...
- 再学Blazor——组件
Blazor 应用基于组件,组件可以复用和嵌套.本文内容如下: 组件类 组件嵌套 组件参数 组件对象 1. 组件类 所有组件都是继承 ComponentBase 组件基类,razor 文件默认继承 C ...
- Flex 布局项目实战,好像没那么难!
在上篇文章别再用 float 布局了,flex 才是未来!中,我们聊到 Flex 布局才是目前主流的布局方式.在文章最后,我们还贴了一个案例,并且还浅浅地讲解了一下. 有些小伙伴说,这讲解得太粗了,要 ...
- RLChina理论三:强化学习基础
强化学习基础 马尔可夫决策过程就是在,环境自发做出转变,是个随波逐流的过程,At是智能体的行动,在St环境状态下加入At动作,c才进入下个状态S(t+1),即环境有自己的变化,也加入了智能体的决策. ...
- Python 数学函数和 math 模块指南
Python 提供了一组内置的数学函数,包括一个广泛的数学模块,可以让您对数字执行数学任务. 内置数学函数.min() 和 max() 函数可用于在可迭代对象中查找最低或最高值: 示例:查找可迭代对象 ...
- go中的内存逃逸
内存逃逸(memory escape)是指在编写 Go 代码时,某些变量或数据的生命周期超出了其原始作用域的情况.当变量逃逸到函数外部或持续存在于堆上时,会导致内存分配的开销,从而对程序的性能产生负面 ...