(二)、==和equals的区别

本文通过示例详细解析了Java中==与equals方法的区别,包括String、自定义类Person的实例对比,强调equals方法重写的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


public class Person {
String name;
public Person(String name){
this.name = name;
}
@Override
public boolean equals(Object anObject){
//仿照String类的equals方法来写
if(this == anObject) return true;
if(anObject instanceof Person){
Person p = (Person)anObject;
if(p.name.equals(this.name))
return true;
}
return false;
}
}

public class Equals==Test {
public static void main(String[] args) {
String str = new String("abc"); //语句(1)
String str2 = new String("abc");//语句(2)

System.out.println(str == str2);//语句(3)
System.out.println(str.equals(str2));//语句(4)

Object object = new Object();//语句(5)
Object object2 = new Object();//语句(6)

System.out.println(object == object2);//语句(7)
System.out.println(object.equals(object2));//语句(8)

Person p = new Person("zhangsan");//语句(9)
Person p2 = new Person("zhangsan");//语句(10)

System.out.println(p == p2);//语句(11)
System.out.println(p.equals(p2));//语句(12)
}
}

问题1:执行完语句(3)(4)打印的结果是什么?说明理由
解答:执行完语句(3)(4)打印的结果是false和true。
分析:str和str2是引用,它们指向不同的对象,内存地址不同,所以str==str2为false。我们看看String的equals方法的源码,它是对Object的equals方法的重写:
public boolean equals(Object anObject) {   
if (this == anObject) { return true; }
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++]) return false;
}
return true;
}
}
return false;

注意:String类把Object类的equals方法重写了,所以它比较的确实是对象的内容。

问题2:执行完语句(7)(8)打印的结果是什么?说明理由。
解答:执行完语句(7)(8)打印的结果是false和false。
分析:object和object2是引用,它们指向不同的对象,内存地址不同,所以object==object2为false。
查看jdk的源代码,我们发现equals方法定义在Object类里面,所以所有类都有这个方法。Object类是这样定义equals方法的:
public boolean equals(Object obj) {return (this == obj); } 

从这里可以看出,Object类里面的equals方法和==是等价的,它比较的也是内存地址。

问题3:执行完语句(11)(12)打印的结果是什么?说明理由。
解答:执行完语句(11)(12)打印的结果是false和false。分析:Person类没有重写Object类的equals方法。

总结:==和equals()方法有什么区别?我们不能笼统的说,equals方法比较的是内容。我们应该说"=="永远比较的是内存地址。对于equals方法,在Object类的层次上来说,它比较的是内存地址,和"=="一样。如果一个子类重写了Object类的equals方法,这个时候这个equals方法才正真比较的是内容。

要求:在自定义类的时候,如果要进行相等性的比较,必须要重写父类的equals方法。怎么重写equals方法,它有固定的模式(要重写hashCode,下次课讲),对于Person类 来说,如果两个Pereson的name相同,它就应该返回true,否则返回false。参见Person类的equals方法。
<think>嗯,用户问的是“==”equals的关系区别。这个问题在Java里挺常见的,可能用户刚开始学编程,或者在面试准备中遇到了这个问题。我需要先回忆一下这两个操作符的基本概念,然后整理它们的区别适用场景。 首先,“==”是操作符,而equals是方法。这应该是它们的根本区别。那具体来说,“==”比较的是对象的引用是否指向同一内存地址,也就是是否同一个对象。而equals方法通常是用来比较对象的内容是否相等,但这也取决于类如何重写这个方法。比如,String类重写了equals,所以比较的是字符串内容,而如果自己创建的类没有重写equals,那么默认还是使用Object类的equals,这时候“==”一样,比较的是引用。 然后,可能需要举例子来说明。比如两个String对象,用new创建的,虽然内容相同,但“==”比较的是地址,所以返回false,而equals比较内容,返回true。但如果是字面量创建的字符串,Java可能会优化,让它们指向同一个对象,这时候“==”可能返回true。这可能需要注意。 接下来,基本数据类型包装类的情况。比如intInteger,当使用“==”比较时,如果Integer对象在缓存范围内(-128到127),可能会返回true,超出的话就是false,这时候应该用equals来比较值。比如Integer a = 100Integer b=100,a==b是true,但如果是200,a==b就是false,这时候需要用equals。 还要注意null的情况。如果一个对象为null,调用equals会抛出NullPointerException,所以在使用前需要检查是否为null。而“==”比较null的时候不会有问题,比如obj == null这样的判断是安全的。 另外,覆盖equals方法时通常也要覆盖hashCode方法,这是Java中的约定,特别是当对象用在散列表中的时候。不过用户的问题可能不涉及这部分,但如果有更深入的问题可能需要提到。 总结的话,应该分点说明区别,包括比较的内容、适用场景、例子等。结构上可能需要先解释各自的定义,再对比,然后举例子,最后总结使用场景。用户可能需要具体的代码示例来理解,所以例子很重要。 需要确保语言准确,比如“==”比较的是对象的内存地址,而equals比较内容,但要注意默认情况下的equals行为。可能用户会混淆这两个,特别是在处理字符串的时候,常见的陷阱就是用了“==”而不是equals,导致意外的结果。 另外,可能用户想知道什么时候用哪个,所以给出使用建议:基本数据类型用“==”,对象比较内容用equals,但要确保该类正确重写了equals方法。如果是自定义对象,需要自己重写equals来实现内容的比较。 最后检查是否有遗漏点,比如基本类型引用类型在使用“==”时的不同,或者自动装箱带来的影响。例如,两个Integer对象使用“==”比较,如果值相同但在缓存范围外,会返回false,这时候应该用equals。</think>### "==" equals 的关系与区别详解 #### 一、核心区别 1. **本质不同** - **`==`**:是运算符,用于**比较对象的引用(内存地址)**或基本数据类型的值。 - **`equals()`**:是方法,用于**比较对象的内容是否逻辑相等**(需依赖具体类的实现)。 2. **行为对比表** | 场景 | == 的行为 | equals 的默认行为 | equals 的重写行为(如 String) | |----------------|--------------------------|--------------------------|--------------------------------| | 基本数据类型 | 比较值是否相等 | 不适用 | 不适用 | | 对象引用 | 比较内存地址是否相同 | 比较内存地址是否相同 | 比较对象内容是否相等 | --- #### 、深入分析 1. **基本数据类型比较** ```java int a = 5; int b = 5; System.out.println(a == b); // true(比较值) ``` 2. **对象引用比较(未重写 equals)** ```java Object obj1 = new Object(); Object obj2 = new Object(); System.out.println(obj1 == obj2); // false(不同内存地址) System.out.println(obj1.equals(obj2)); // false(Object 默认用 == 实现) ``` 3. **String 的特殊性** ```java String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); // false(不同对象) System.out.println(s1.equals(s2)); // true(String 重写 equals 比较内容) ``` 4. **自动装箱陷阱(Integer 缓存)** ```java Integer i1 = 127; Integer i2 = 127; System.out.println(i1 == i2); // true(-128~127 缓存范围内) Integer i3 = 200; Integer i4 = 200; System.out.println(i3 == i4); // false(超出缓存范围) System.out.println(i3.equals(i4)); // true(比较值) ``` --- #### 三、关键规则总结 1. **`==` 使用场景** - 比较基本数据类型的值 - 检查对象是否为同一实例 - 判断引用是否为 `null` 2. **`equals()` 使用场景** - 需要逻辑相等性判断时(如字符串内容、自定义业务规则) - 注意必须重写 `hashCode()` 以保持一致性(HashMap/HashSet 依赖此规则) --- #### 四、自定义类示例 ```java class Person { String name; @Override public boolean equals(Object o) { if (this == o) return true; // 优化:同一对象直接返回 true if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name); // 实际内容比较 } } ``` --- #### 五、常见误区 1. **混淆字符串字面量与对象** ```java String a = "text"; // 可能指向字符串常量池同一对象 String b = new String("text"); System.out.println(a == b); // false ``` 2. **未处理 null 导致的 NPE** ```java String str = null; System.out.println(str.equals("test")); // 抛出 NullPointerException System.out.println("test".equals(str)); // 安全写法(推荐) ``` --- #### 六、最佳实践 1. 对象内容比较时,优先使用重写后的 `equals()` 2. 对可能为 `null` 的对象,采用逆向调用方式:`"常量".equals(变量)` 3. 自定义类必须同时重写 `equals()` `hashCode()`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值