必须用equals(),因integer等包装类重写了equals比较数值,而==在-128~127缓存范围内比较地址可能为true,范围外或new创建时必为false;且equals需防null和跨类型调用失败,推荐objects.equals()。

面试官问“Java包装类比较用equals还是==”,不是让你背口诀,而是考察你对内存模型、自动装箱机制和重写逻辑的真实理解。答错不丢分,但只说“用equals”就暴露基础漏洞。
包装类的==不是简单比地址
Integer、Long等包装类在-128到127范围内会缓存对象(IntegerCache),超出范围则每次new都新建对象:
- Integer a = 100, b = 100; → a == b 是 true(共用缓存对象)
- Integer c = 200, d = 200; → c == d 是 false(各自新建)
- 这个范围可调(-XX:AutoBoxCacheMax),但默认就是-128~127
equals()也不是万能安全牌
包装类的equals()确实重写为比较数值,但它有隐含前提:
- 必须确保两个对象都不为null,否则调用equals会抛NullPointerException
- 不同包装类型间调用equals可能返回false:new Integer(1).equals(new Long(1)) → false(类型检查不通过)
- 推荐写法:Objects.equals(a, b),它内部做了null安全处理
面试常挖的三个陷阱点
光说“包装类用equals”远远不够,面试官大概率追问:
- 为什么Integer.valueOf(100) == Integer.valueOf(100)为true,而new Integer(100) == new Integer(100)为false?(考缓存机制与对象创建方式)
- 如果自己写一个Money类,要支持金额相等判断,equals该怎样重写?(考重写规范:先判this==obj,再判null和class,最后比字段)
- String str = "abc"; 和 String str = new String("abc"); 的==和equals结果分别是什么?为什么?(延伸考常量池,验证是否真懂引用本质)
一句话总结答题策略
包装类比较优先用equals(),但必须意识到:它依赖重写逻辑、受null影响、跨类型无效;==看似危险,但在确定值在缓存范围内且非null时,反而更高效——关键不是选哪个,而是清楚每个符号背后发生了什么。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











