当前位置: 首页 > article >正文

详解equals底层原理

    equals 方法是 Java 中用于比较两个对象是否“相等”的方法。在 Java 中,每个类都继承自 java.lang.Object 类,而 equals 方法正是定义在 Object 类中的一个方法。默认情况下,Object 类的 equals 方法比较的是两个对象的内存地址(即引用是否指向同一块内存),而不是它们的内容。因此,如果你希望在自定义的类中实现基于内容的比较,你需要重写 equals 方法。

解疑:

  • 为什么上面说equals 方法比较的是两个对象是否“相等”,我写的 "abc".equals("abc")  比较的是内容值? 

答案:在Java中,Object 类是所有类的超类(理解为它是所有类的父类或祖宗类),它提供了一个默认的 equals 方法实现。这个默认实现是比较两个对象的引用是否相同,即它们是否指向内存中的同一个对象。

(1)在Test类中输入Object:

Object

(2)左手按住Ctrl键,右手用鼠标点击Object 就可以查看Object类的底层源代码

(3)使用Ctrl+f键 输入equals 找到 equals实现方法

解读代码:

  • public boolean equals(Object obj):该方法接受一个类型为 Object 的参数 obj,并返回一个布尔值。

  • return (this == obj);:它使用 == 运算符比较当前对象(this)与传入的对象(obj)的引用。

        所以Object类的equals方法的底层源代码是用“==”来进行比较,当用于对象时,== 检查两个引用是否指向内存中的同一个对象,即它们是否是同一个对象实例。或者是说比较地址值(即对象的引用)

        这种实现仅仅是比较两个对象的引用是否相同,而不是比较对象的内容(例如它们的属性或状态)。这就是为什么在大多数情况下,我们需要根据对象的实际内容重写 equals 方法。所以当你写的 "abc".equals("abc") 时实际上是调用了子类String 重写的equals方法。

String类重写了父类Object 的equals方法,内容如下:

  public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        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) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

分析如下: 

同样的当你使用equals比较两个Integer类型的值时,Integer类也重写了equals方法,代码如下:

  public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

分析如下: 

  • 如果定义一个Person类,调用equals方法比较两个对象(如下代码),equals方法比较对象的内容(例如它们的属性或状态)还是比较是否是同一个对象呢?

 Person person1=new Person("小明",18);
 Person person2=new Person("小明",18);
 System.out.println(person1.equals(person2));

答案:比较是否是同一个对象。Person类因为本身没有equals方法,但它是Object的子类(Object 类是所有类的超类,所以Person默认继承了Object类)Person调用是父类的equals方法,而父类的equals方法底层实现代码如下:

  public boolean equals(Object obj) {
        return (this == obj);
    }

        代码是用“==”来进行比较,当用于对象时,== 检查两个引用是否指向内存中的同一个对象,显然person1和person2是两个不同的对象(变量名不同)。如果我们想要有一个 Person 类,并且你想要比较两个 Person 对象是否具有相同的名字和年龄,那么你需要重写 equals 方法来比较这些属性,而不是仅仅比较它们的引用。


重写equals代码思路:

1.从特殊到一般:先把最特殊的情况写出来(即两个对象是同一个对象:对象的引用相同都指向同一个对象)

2.判断是否是同一类(即判断是不是Person类)

obj instanceof Person

3.判断属性值是否相等

以下是重写equals的详细代码:

package Test;

public class Person {
    private String name;
    private int age;
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
//    思路:从特殊到一般!!!
//    如果是同一个对象直接返回true  同一个对象相当于对象引用指向同一对象
//    判断同类类型的对象的属性是否相同,先判断同一类型,再判断属性值
//  重写equals方法:
    public boolean equals(Object obj) {
        if (this == obj){
            return true;
        } else if (obj instanceof Person) {
            Person person=(Person) obj;
            return person.name.equals(name) && person.age==age;
        }
        return false;
    }
    public static void main(String[] args) {
        Person person1=new Person("小明",18);
        Person person2=new Person("小明",18);
        System.out.println(person1.equals(person2));
    }
}

http://www.kler.cn/news/357956.html

相关文章:

  • 【力扣打卡系列】滑动窗口与双指针(无重复字符的最长子串)
  • word取消自动单词首字母大写
  • OpenAI Prompt generation - 生成和优化Prompt的Prompt
  • distinct 和 group by
  • 恒定电流下有功率密度,功率密度体积分就是恒定电流的功率
  • 2024最新 无人机 数据集(不定期更新)
  • 【flutter】哪些APP使用了flutter框架开发
  • 如何修改jupyter notebook的工作目录
  • Chromium 加载chrome.dll过程分析c++
  • 使用Spring Boot打造中小型医院网站
  • 使用Three.js和Force-Directed Graph实现3D知识图谱可视化
  • 【高等数学学习记录】极限存在准则,两个重要极限
  • bash之流程控制
  • 基于SSM+微信小程序的电子点餐管理系统(点餐1)
  • 电影评论网站:Spring Boot技术实践
  • 【微服务】微服务API网关详解:提升系统效率与安全性的关键策略
  • 操作系统学习笔记-1.3操作系统引导,虚拟机
  • 【PHP小课堂】一起学习PHP中的反射(一)
  • 【经管】比特币与以太坊历史价格数据集(2014.1-2024.5)
  • 文件工具类 - C#小函数类推荐