Java 中 == 与 equals()的区别笔记
·
== 与 equals() 的区别
在 Java 中,== 和 equals() 都可以用于比较两个值是否相等,但它们适用的类型、比较的内容和结果却有所不同。
一、== 运算符
基本概念:
==是一个 运算符,用于比较 两个操作数的值是否相等。
使用规则:
| 数据类型 | 比较内容 |
|---|---|
| 基本数据类型 | 比较的是 值 |
| 引用数据类型 | 比较的是 内存地址(即对象引用) |
举例说明:
int a = 100;
int b = 100;
System.out.println(a == b); // true,值相等
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false,两个不同的对象,地址不同
String s3 = "hello";
String s4 = "hello";
System.out.println(s3 == s4); // true,字符串常量池中引用的是同一对象
二、equals() 方法
基本概念:
equals()是 Object 类 提供的方法,用于判断两个对象是否“相等”。- 默认实现(在 Object 类中)是 比较对象的地址(即:
this == obj)。
方法签名:
public boolean equals(Object obj)
用法与重写:
- 若一个类没有重写
equals(),则其效果与==相同; - 若类重写了
equals(),则可自定义比较逻辑(如按值、按字段比较)。
Object 类中的 equals 源码:
public boolean equals(Object obj) {
return (this == obj); // 默认是地址比较
}
三、实际对比说明
示例代码:
String a = new String("ab"); // 在堆中创建新对象
String b = new String("ab"); // 在堆中创建新对象
String aa = "ab"; // 在字符串常量池中
String bb = "ab"; // 指向常量池中的同一个对象
System.out.println(a == b); // false,堆中两个不同对象
System.out.println(a.equals(b)); // true,String重写了equals,比较内容
System.out.println(aa == bb); // true,常量池中同一对象
System.out.println(a == aa); // false,堆对象 ≠ 常量池对象
System.out.println(42 == 42.0); // true,int 自动转换为 double 后值仍相等
四、String 类中 equals() 的实现
String 类重写了 equals() 方法,使得其比较内容而不是地址:
源码:
public boolean equals(Object anObject) {
// 第一步:检查是否是同一个对象引用(快速路径)
if (this == anObject) {
return true;
}
// 第二步:检查对象是否为String类型(类型检查)
if (anObject instanceof String) {
// 类型安全转型
String anotherString = (String)anObject;
// 第三步:获取当前字符串的长度
int n = value.length;
// 第四步:比较字符串长度(关键优化)
// 如果长度不同则必然不相等
if (n == anotherString.value.length) {
// 第五步:获取字符数组引用
char v1[] = value; // 当前字符串的字符数组
char v2[] = anotherString.value; // 比较字符串的字符数组
int i = 0;
// 第六步:逐个字符比较
// 使用自减计数器的循环(效率优化)
while (n-- != 0) {
// 发现不同字符立即返回false
if (v1[i] != v2[i])
return false;
i++; // 移动到下一个字符
}
// 第七步:所有字符匹配返回true
return true;
}
}
// 第八步:对象不是String类型或长度不同返回false
return false;
}
小结:
- 同引用:立即返回
true; - 非 String 类型:返回
false; - 逐字符比较内容:若完全一致,则返回
true。
五、equals() 的两种使用场景
| 是否重写 equals() | 行为描述 |
|---|---|
| 没有重写 | 等价于 ==,比较地址 |
| 重写了 | 比较对象字段内容(如字符串、集合等) |
六、总结对比表
| 比较项 | == |
equals() |
|---|---|---|
| 类型 | 运算符 | 方法(Object类继承) |
| 适用对象 | 基本类型和引用类型 | 只能用于对象 |
| 基本类型行为 | 比较值 | 不适用 |
| 引用类型行为 | 比较内存地址 | 默认比较地址,重写后可自定义内容比较 |
| 是否可重写 | 不可 | 可由子类重写 |
| 常用于 | 判断是否同一个对象 | 判断两个对象内容是否相等 |
| String默认行为 | 比较引用地址 | 比较字符串值(内容) |
七、使用建议
-
判断值是否相等:使用
equals(),特别是 String、包装类、集合等。 -
判断是否为同一对象引用:使用
==。 -
判断 null 前应先反向调用:
if ("abc".equals(s)) // 推荐:避免空指针异常
更多推荐



所有评论(0)