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

详解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.mrgr.cn/news/54977.html

相关文章:

  • JSP + Servlet:构建动态Web应用的经典组合
  • iOS IPA上传到App Store Connect的三种方案详解
  • 动态规划-子数组系列——413.等差数列划分
  • 鸿蒙开发 四十五 鸿蒙状态管理(嵌套对象界面更新)
  • Flux.merge 使用说明书
  • 深入vue2[更新中]
  • 滑动窗口,水果成篮 , 找到字符串中所有字母异位词 ,串联所有单词的子串
  • 练习题 - Scrapy爬虫框架 Selectors 数据选择器
  • 权限管理系统的详细解析与实现
  • 栈与队列的常见接口的实现
  • yolov8实例分隔
  • OpenCV图像处理——查找线条的转折点
  • 鸿蒙中富文本编辑与展示
  • Guava防击穿回源-同步防击穿
  • 数据结构7——二叉树的顺序结构以及堆的实现
  • jupyter notebook中执行过程中更新模块代码,再执行没有更新执行
  • 机器学习与神经网络:诺贝尔物理学奖的新纪元
  • Vue中使用路由
  • 数据结构:二叉树、堆
  • python+Mosh网课笔记04
  • 计算机毕业设计 基于java个性化智能学习系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
  • 关于SSD1306的OLED的显示的研究
  • 一图秒懂色彩空间和色彩模型
  • 云计算-----单机LNMP结构WordPress网站
  • 从DexMV、VideoDex、MimicPlay到SeeDo:从人类视频中学习:机器人的主流训练方法之一
  • 网盘直链下载神器NDM