核心问题是误用==导致引用比较替代数值比较;应统一用Objects.equals()判等、compareTo()或解包比大小,禁用==比较包装类数值。

Java 中包装类数值比较出错,核心问题不是“怎么比”,而是“误把引用比较当数值比较”。只要用了 ==,就大概率掉进逻辑漏洞——它不看数字大小,只看是不是同一个对象。
别用 == 比数值,这是第一铁律
== 对 Integer、Long、Boolean 等包装类,永远比较的是内存地址。JVM 缓存机制(如 Integer 的 -128~127 范围)会让部分相等值“碰巧”返回 true,超出范围或经反序列化、new 构造后就必然 false。这不是偶发 bug,是确定性陷阱。
- ✅
Integer a = 100; Integer b = 100; a == b → true(缓存复用) - ❌
Integer c = 200; Integer d = 200; c == d → false(各自新建) - ❌
Integer e = new Integer(100); Integer f = 100; e == f → false(new 总不走缓存)
判断相等:统一用 Objects.equals()
它自动处理 null,不触发拆箱,语义清晰,适配所有包装类:
-
Objects.equals(a, b)返回true当且仅当两者数值相等,或都为null - 比
a != null && a.equals(b)更简洁,比a.equals(b)更安全(避免 NPE) - 对 Boolean、Double、Float 同样适用,无需额外分支
判断大小:用 compareTo() 或显式解包
相等性用 equals,大小关系必须用数值语义方法:
- 推荐
a.compareTo(b) > 0—— 返回int,天然支持排序、条件判断,且能处理 null(需先校验) - 若确定非 null,可用
a.intValue() > b.intValue(),但绝不建议裸写a > b(隐式拆箱 + NPE 风险) - 涉及 Float/Double 时,必须用
Float.compare(a, b)或Double.compare(a, b),避开 NaN 引发的==失效
警惕高危混合场景
这些写法表面正常,实则极易崩溃或逻辑错乱:
-
if (user.getAge() == 18)——getAge()返回Integer,为null时直接 NPE -
return flag ? 1 : status;—— 三元运算符强制统一类型,status为null时拆箱失败 -
switch (code)(code 是 Integer)—— Java 14+ 支持,但传入null运行时报错 - JSON 反序列化后的字段、RPC 响应体、Optional.orElseGet() 构造的对象,基本都不走缓存,
==必败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











