应优先使用objects.equals()替代a.equals(b),避免空指针和类型不匹配问题;能用基本类型就不用包装类;跨类型比较需显式转换;警惕自动拆箱引发的npe。

避免在包装类比较中踩坑,核心不是“怎么用 equals”,而是“别让 equals 成为唯一或首选的裸调用方式”。真正安全的做法是绕过直接调用 equals 的风险点,用更鲁棒的替代方案。
优先用 Objects.equals() 替代 a.equals(b)
直接写 a.equals(b) 有两大隐患:a 为 null 时抛 NPE;b 类型不匹配(比如传入 String 或 Long)时返回 false,但你可能误以为是数值不等。Objects.equals(a, b) 内部已处理所有组合:
• null == null → true
• null == 非 null → false
• 非 null 且类型一致 → 调用 a.equals(b)
• 非 null 但类型不同 → 直接返回 false,语义清晰
推荐无条件使用它,无论变量来源是方法参数、集合取值还是配置解析结果。
能用基本类型就不用包装类
如果业务逻辑中该值天然不可能为 null(如计数器、ID、状态码),声明和传递时直接用 int/long/boolean 等基本类型:
• 避免装箱开销和缓存陷阱
• == 比较完全合法且高效
• 不会出现 NPE 或类型误判
只有当需要表达「缺失」语义(如数据库字段允许 NULL)或必须放入泛型容器(List
跨类型或混合比较要显式转换
Integer.equals(Long)、Integer.equals(int) 看似可行,实则危险:
• new Integer(5).equals(new Long(5)) → false(类型检查失败)
• Integer.valueOf(5).equals(5) → true(int 自动装箱为 Integer)
但这种隐式行为依赖编译器,可读性差,且一旦一方是 double 或字符串就失效
若需跨类型比数值,统一转成基本类型再比:
• a != null && b != null && a.longValue() == b.longValue()
• 或用 BigDecimal 处理浮点精度敏感场景
警惕自动拆箱带来的空指针
看似简单的 if (obj == 5) 或 int x = obj + 1,本质是自动拆箱(调用 obj.intValue())。只要 obj 为 null,立刻抛 NPE。
这类写法隐蔽性强,尤其在复杂表达式或链式调用中。防御方式只有两个:
• 显式判空后再拆箱
• 改用 Objects.equals(obj, 5) —— 它不会触发拆箱,只做安全的对象级比较
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











