跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何区分 == 与 equals() 在字符串比较及自定义对象比较中的本质区别

== 比较引用是否指向同一内存地址,equals() 比较内容是否逻辑相等;字符串字面量因常量池可能使 == 为 true,但应始终用 equals() 判断内容;自定义类需重写 equals() 和 hashCode() 才能按业务逻辑比较。 区分
==
和
equals()
的关键,不在于“哪个更好”,而在于“它们本来就在做不同的事”:一个看是不是同一个东西(地址),一个看内容是不是一样(逻辑相等)。 字符串比较:常量池让 == 有时“碰巧”为 true String 是最典型的例子,但容易让人误解。根本原因在于 Java 的字符串常量池机制:
==
比较的是两个引用是否指向堆中同一块内存地址。比如
new String("hello") == new String("hello")
一定是
false
,因为每次
new
都新建对象,地址不同。
equals()
在 String 类中已被重写,逐字符比内容。所以上面那行的
equals()
返回
true
。 但像
String s1 = "hello"; String s2 = "hello";
这种字面量赋值,JVM 会把它们放进常量池并复用同一对象,此时
s1 == s2
也返回
true
——这不是 equals 生效了,而是地址真相同了。 别依赖这种“碰巧”。生产代码中判断字符串内容是否一致,一律用
equals()
;用
==
只适合极少数场景,比如确认是否是某个特定的空字符串常量或单例标识。 自定义对象比较:默认 equals() 和 == 完全等价 如果你写了一个类,比如
Person
,没动过
equals()
方法,那么它的行为就和
Object
类里的一模一样:
public boolean equals(Object obj) { return (this == obj); }
—— 看,底层就是
==
。 所以
new Person("张三", 25).equals(new Person("张三", 25))
一定返回
false
,哪怕所有字段都一样,因为是两个不同对象。 要让它按业务规则比较(比如姓名+年龄相同就算相等),必须手动重写
equals()
,且必须同时重写
hashCode()
,否则放进
HashMap
或
HashSet
会出现存进去却找不到的问题。 什么时候该用 ==,什么时候该用 equals()? 看目的,不看类型: 想确认两个变量是不是指向同一个实例(比如检查回调是否重复注册、校验单例对象、判断状态机当前是否处于某个固定实例状态),用
==
。 想确认两个对象在业务意义上是否“相等”(比如两个订单金额和商品清单一样、两个用户身份证号相同),必须用重写后的
equals()
。 基本类型(
int
、
char
等)只能用
==
,没有
equals()
方法;包装类(
Integer
、
Character
)建议统一用
.equals()
,避免因缓存(如 -128~127)导致行为不一致。 为防空指针,推荐用
Objects.equals(a, b)
,它内部自动处理了
null
安全问题。

相关文章