为什么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= ...
随机推荐
- 【Python】代理池针对ip拦截破解
代理池是一种常见的反反爬虫技术,通过维护一组可用的代理服务器,来在被反爬虫限制的情况下,实现数据的爬取.但是,代理池本身也面临着被目标网站针对ip进行拦截的风险. 本文将详细介绍代理池针对ip拦截破解 ...
- 其它——paramiko模块的使用
文章目录 paramiko 一 介绍 二 通过用户名密码方式远程执行命令 三 通过用户名密码方式上传下载文件 四 通过公钥私钥远程执行命令 五 通过公钥私钥远程上传下载文件 六 通过私钥字符串远程连接 ...
- 将GitBash设置为VS Code的默认终端
这个东西搞了半天,真的无语...网上的东西都太旧了 注意:"terminal.integrated.shell.windows"自2021年4月起已弃用. 1.首先打开设置 2.进 ...
- solidity入门
1. solidity 简介 Solidity(中文名称:Solidity 语言)是一种面向智能合约(Smart Contracts)的高级编程语言,最初由以太坊(Ethereum)的团队开发并用于以 ...
- [ABC212E] Safety Journey 题解
Safety Journey 题目大意 给定一张缺少了 \(m\) 条边的 \(n\) 个点的完全图和一个正整数 \(k\),你需要求出满足以下条件的序列 \(A\) 的数量: \(A\) 的长度为 ...
- CC BY-SA 4.0原文及翻译
CC BY-SA 4.0原文及翻译 英文参考链接 中文参考链接 原文: Attribution 4.0 International (CC BY 4.0) This is a human-readab ...
- 每天5分钟复习OpenStack(七)内存虚拟化
标题中的存储虚拟化,涉及到两个方面,分别是内存和磁盘的虚拟化技术.内存的虚拟化就不得不提EPT和VPID 技术. 首先申明下本人其实不想写一些纯理论的东西,但是架不住面试经被问,为此特将一些特别复杂的 ...
- 递归+记忆化递归+DP:斐波那契数列
递归:算法复杂度O(2^N) 1 int fib(int n) 2 { 3 if (n == 0) 4 { 5 return 0; 6 } 7 if (n == 1) 8 { 9 return 1; ...
- .NET8 Blazor的Auto渲染模式的初体验
.NET8发布后,Blazor支持四种渲染方式 静态渲染,这种页面只可显示,不提供交互,可用于网页内容展示 使用Blazor Server托管的通过Server交互方式 使用WebAssembly托管 ...
- 神经网络入门篇:神经网络的梯度下降(Gradient descent for neural networks)
神经网络的梯度下降 在这篇博客中,讲的是实现反向传播或者说梯度下降算法的方程组 单隐层神经网络会有\(W^{[1]}\),\(b^{[1]}\),\(W^{[2]}\),\(b^{[2]}\)这些参数 ...