面试官: 请问 equals() 和 "==" 有什么区别?
应聘者:
equals()方法用来比较的是两个对象的内容是否相等, 由于所有的类都是继承自 java.lang.Object 类的, 所以适用于所有对象, 如果没有对该方法进行覆盖的话, 调用的仍然是 Object 类中的方法, 而 Object 中的 equals 方法返回的却是 == 的判断;
"==" 比较的是变量 (栈) 内存中存放的对象的 (堆) 内存地址, 用来判断两个对象的地址是否相同, 即是否是指相同一个对象.
equals()作用
equals() 的作用是用来判断两个对象是否相等.
equals() 定义在 JDK 的 Object.java 中. 通过判断两个对象的地址是否相等 (即, 是否是同一个对象) 来区分它们是否相等. 源码如下:
- public boolean equals(Object obj) {
- return (this == obj);
- }
既然 Object.java 中定义了 equals()方法, 这就意味着所有的 Java 类都实现了 equals()方法, 所有的类都可以通过 equals()去比较两个对象是否相等. 但是, 我们已经说过, 使用默认的 "equals()" 方法, 等价于 "==" 方法. 因此, 我们通常会重写 equals()方法: 若两个对象的内容相等, 则 equals()方法返回 true; 否则, 返回 fasle.
下面根据 "类是否覆盖 equals()方法", 将它分为 2 类.
若某个类没有覆盖 equals()方法, 当它的通过 equals()比较两个对象时, 实际上是比较两个对象是不是同一个对象. 这时, 等价于通过 "==" 去比较这两个对象.
我们可以覆盖类的 equals()方法, 来让 equals()通过其它方式比较两个对象是否相等. 通常的做法是: 若两个对象的内容相等, 则 equals()方法返回 true; 否则, 返回 fasle.
下面, 举例对上面的 2 种情况进行说明:
没有覆盖 equals()方法的情况
- public class EqualsTest {
- public static void main(String[] args) {
- // 新建 2 个相同内容的 Person 对象,
- // 再用 equals 比较它们是否相等
- User user1 = new User("James", 100);
- User user2 = new User("James", 100);
- System.out.printf("比较结果:" + user1.equals(user2));
- }
- /**
- * @desc User 类.
- */
- static class User {
- int age;
- String name;
- public User(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public String toString() {
- return name + "-" + age;
- }
- }
- }
运行结果:
比较结果: false
结果分析: 我们通过 user1.equals(user2) 来 "比较 user1 和 user2 是否相等时". 实际上, 调用的 Object.java 的 equals()方法, 即调用的 (user1==user2) . 它是比较 "p1 和 p2 是否是同一个对象". 而由 user1 和 user2 的定义可知, 它们虽然内容相同; 但它们是两个不同的对象, 因此, 返回结果是 false.
覆盖 equals()方法的情况
修改上面的 EqualsTest, 覆盖 equals()方法:
- public class EqualsTest {
- public static void main(String[] args) {
- // 新建 2 个相同内容的 Person 对象,
- // 再用 equals 比较它们是否相等
- User user1 = new User("James", 100);
- User user2 = new User("James", 100);
- System.out.printf("比较结果:" + user1.equals(user2));
- }
- /**
- * @desc User 类.
- */
- static class User {
- int age;
- String name;
- public User(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public String toString() {
- return name + "-" + age;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- User other = (User) obj;
- if (age != other.age)
- return false;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- return true;
- }
- }
- }
运行结果:
比较结果: true
结果分析: 我们在 EqualsTest.java 中重写了 User 的 equals()函数: 当两个 User 对象的 name 和 age 都相等, 则返回 true. 因此, 运行结果返回 true.
== 的作用
"==": 它的作用是判断两个对象的地址是不是相等. 即判断引用对象是不是指向的堆中的同一个对象, 我们知道, 凡是 new 出来的对象都在堆中. 而对象的引用都存放在栈中, 具体来讲就是放在栈帧中, 我们来看下面一段代码:
- public static void main(String[] args) {
- User user1 = new User("James", 100);
- User user2 = new User("James", 100);
- System.out.println("user1.equals(user2):" + user1.equals(user2));
- System.out.println("user1==user2:" + (user1==user2));
- }
输出结果:
- user1.equals(user2):true
- user1==user2:false
用内存图表示如下:
指向的是堆中两块不同的区域, 所以用 "==" 比较时返回的是 false.
来源: https://www.cnblogs.com/marsitman/p/11181610.html