
大家好,我是程序员卡卡罗特,一个分享宝藏经验的程序员。
前阵子组里来了个新人,交给他一个不算复杂的任务。
我们公司呢,每周四发版,上线前两天都会组织代码评审,那一次也正常过了——功能简单,大家都没太细看。
但工作这么多年,我上线前,我一般还会二次CR,这是一个很好的习惯。
果然,在最后一遍过代码时,IDEA 给我亮了个“智能提示”,我心里“咯噔”一下:

emm,大事不妙!如果没二次review,麻烦就大了!然后才有了这篇文章。
各位做 Java 的小伙伴,不妨先猜猜看:下面这段代码执行后,会打印“不相等”吗?
public static void main(String[] args) {
Integer total = 168;
Integer count = 168;
if (total != count) {
System.out.println("不相等!!!");
} else {
System.out.println("相等!");
}
}
很多人的第一反应是:“两个都是 168,那肯定相等啊!”
实际运行结果是:

打印了“不相等”。
这其实是很多 Java 初学者甚至一些有经验的开发者容易混淆的点:
•
int 是基本类型,比较的是数值;
•
Integer 是包装类型(引用类型),== 比较的是内存地址。
也就是说,即使两个 Integer 的值相同,只要它们不是同一个对象,== 就会返回 false。
再看这段:
Integer total2 = 100;
Integer count2 = 100;
if (total2 != count2) {
System.out.println("不相等!");
} else {
System.out.println("相等!");
}
上面这段代码呢?会打什么呢?

你会发现,这里打印的是 “相等!”。
是不是更迷惑了?
同样的写法,为什么 168 不相等,100 就相等?
Java 对 Integer 在 -128 到 127 之间的值做了缓存(可通过 JVM 参数调整上限)。
在这个区间内,Integer.valueOf() 会返回**缓存中的同一个对象**;超出这个区间,每次都会创建新对象。
所以:
•
Integer a = 100; 和 Integer b = 100; 指向同一个对象,== 为 true;
•
Integer a = 168; 和 Integer b = 168; 指向不同对象,== 为 false。
如果你用 new Integer(100),那即使值是 100,也会创建新对象,== 也会是 false。
Objects.equals()避免空指针,最安全。
if (!Objects.equals(total, count)) {
// 不相等逻辑
}
适用于确定不为 null 的场景。
if (total.intValue() != count.intValue()) {
// 不相等逻辑
}
// 或者自动拆箱
int t = total;
int c = count;
if (t != c) { ... }
compareTo()适用于确定不为 null 且需要比较大小的场景。
if (total.compareTo(count) != 0) {
// 不相等逻辑
}
这个坑说大不大,但一旦在线上出现,大概率会翻车。
核心就三点:
1
Integer 是对象,== 比较的是地址,不是值;
2
缓存机制只在 [-128, 127] 范围内生效,超出范围或主动 new 都会创建新对象;
3
比较 Integer 的值,请用 Objects.equals() 或拆箱后比较。
基础不牢,地动山摇。很多时候线上问题,恰恰就出在这些“以为很简单”的地方。
我是卡卡罗特,一个分享宝藏经验的程序员。我们下期见。