必须用equals()方法比较包装类对象的值,不能用==运算符;因为==比较引用地址,而equals()比较实际值,且objects.equals()可安全处理null。

在 Java 中比较两个包装类对象(如 Integer、Double、Boolean 等)的值是否相等,**必须用 equals() 方法,不能用 == 运算符**。因为 == 比较的是引用是否指向同一个对象,而 equals() 才会比较实际封装的值(前提是该包装类已正确重写 equals() ——所有标准包装类都已重写)。
为什么不能直接用 ==
== 对于包装类对象,本质是比较内存地址。虽然 JVM 对部分小范围整数(-128 到 127)做了缓存(通过 Integer.valueOf()),使得相同值可能复用对象,但这只是优化,不可依赖:
- Integer a = 100, b = 100; → a == b 为 true(缓存生效)
- Integer c = 200, d = 200; → c == d 为 false(超出缓存范围,新建对象)
-
Double x = 1.0, y = 1.0; → x == y 为 false(
Double不缓存,每次都是新对象)
正确做法:使用 equals() 方法
调用包装类的 equals() 方法可安全比较值。它会先判空,再比较内部基本类型值:
Integer a = 128; Integer b = 128; System.out.println(a.equals(b)); // trueDouble x = 3.14; Double y = 3.14; System.out.println(x.equals(y)); // trueBoolean p = true; Boolean q = true; System.out.println(p.equals(q)); // true
注意:equals() 可处理 null 参数(返回 false),但若调用方是 null,会抛 NullPointerException。稳妥写法是:Objects.equals(obj1, obj2)(推荐 JDK 7+)。
特殊情况:自动拆箱与潜在 NPE
有人会写 a == b 期望触发自动拆箱(比如 Integer → int),但前提是两个对象都不为 null。一旦有 null,就会抛出空指针异常:
Integer a = null; int b = 5; System.out.println(a == b); // NullPointerException- 所以不要依赖自动拆箱做安全比较,尤其在不确定是否为空时。
最佳实践总结
- 一律使用
Objects.equals(a, b)—— 它内部处理了null,语义清晰,安全通用 - 避免用
==比较包装类对象,除非你明确知道它们是同一个对象(极少见) - 如果确定非空且需高性能(如密集循环),可先
if (a != null && b != null) then a.equals(b),但通常没必要 - 对
BigDecimal、BigInteger同样适用此原则(它们也是不可变包装类)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











