解读Object类的equals方法

2024-08-21 08:48
文章标签 方法 object 解读 equals

本文主要是介绍解读Object类的equals方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



Object类中的equals方法,使用的是双等号进行的引用的比较


class Student{

String name;

int age;

public Student(){}

public Student(String name;int age){

this.name=name;

this.age=age;

}

}

public class TestStudent{

public static void main(String[] args){

Student stu1 = new Student("Tom",18);

Student stu2 = new Student("Tom",18);

System.out.println(stu1 == stu2);

System.out.println(stu1.equals(stu2));

}

}

上面的两个输出都是false,第一个false是因为stu1和sutu2两个引用分别指向两个不同的对象,两个引用所存放的地址是不同的,所以返回值为false

但是第二个输出语句中,我们调用了两个equals方法来比较两个对象,在这两个对象中,两个学生的姓名相同,年龄也相同,但是比较的结果依然是false,这是为什么呢?

其实,我们在Student类中并没有定义equals方法,这里的equals方法是从Object类中继承来的,而Object类中的equals方法在进行判断的时候,判断的是引用是否相等

Object类中equals方法的源码:

public boolean equals(Object obj){

return (this==obj);

}

可以看到,在Object类中的equals方法,使用的是双等号进行的比较,因此,Object类中的equals方法不能够帮助我们比较两个学生对象的内容是否相等.

这时候我们就需要覆盖Object类的equals方法,由程序员指定两个对象的比较规则.


在覆盖equals方法之前我们先来解决一个疑问:

String str1 = new Sting("abc");

String str2 = new Sting("abc");

System.out.println(str1 == str2);//输入出false

System.out.println(str1.equals(str2));//输出true


我们知道equals方法其实是比较的两个引用的值,这里str1和str2明显是两个不同的引用,但是为什么这里能够输出true呢?

其实在String类里面已经覆盖了equals方法了,这时候不再是使用的Object类的equals方法了.


下面我们来覆盖equals方法:

public boolean equals(Object obj){

//判断obj是否和this相等,保证自反性

if (obj == this) return true;//自己和自己比较,一定是返回true

//判断obj是否为null

if(obj == null) return false;//当前对象不为null,obj对象为null,一定返回false

//判断两个对象的实际类型是否相等,如果不相等,则说明比较的是两个不同种类的对象,应当返回false

if(obj.getClass() != this.getClass()) return false;

Student stu = (Student) obj;//强制类型转换,由于之前已经使用getClass判断过实际类型,因此这里强转安全的

//判断每个属性是否相等

//对于基本类型的属性用"=="比较,对象类型的属性用equals比较

if(this.age == stu.age && this.name.equals(stu.name))

return true;

else return false;

}


总结一下,覆盖equals方法的五个步骤:

1.判断 this == obj

2.判断 obj == null

3.判断两个对象的实际类型(使用getClass()方法)

4.强制类型转换

5.依次判断两个对象的属性是否相等











这篇关于解读Object类的equals方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092689

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

MySql死锁怎么排查的方法实现

《MySql死锁怎么排查的方法实现》本文主要介绍了MySql死锁怎么排查的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言一、死锁排查方法1. 查看死锁日志方法 1:启用死锁日志输出方法 2:检查 mysql 错误

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.