详解Java中==和equals()的区别

 更新时间:2021年11月09日 09:42:33   作者:Code花卷  
这篇文章主要介绍了Java中==和equals()的区别,,==可以使用在基本数据类型变量和引用数据类型变量中,equals()是方法,只能用于引用数据类型,需要的朋友可以参考下

1. ==

== 是运算符,用来判断两个值是否相等,==可以使用在基本数据类型变量引用数据类型变量

1.1 基本数据类型

Java基本数据类型共有八种,可以分为三类

  • 字符类型char
  • 布尔类型boolean
  • 数值类型byte、short、int、long、float、double

这里有个例外,boolean不参与数值运算

int a1 = 10;
int a2 = 10;
System.out.println(a1==a2);  //true

float a3 = 5.0f;
float a4 = 5.0f;
System.out.println(a3==a4);  //true

……

上面给出几组示例,相同数据类型可以相互比较不用多说了,那么不同数据类型呢?

int a1 = 10;
byte b1 = 10;
System.out.println(a1==b1);  //true

char c1 = 'A';
int c2 = 65;
System.out.println(c1 == c2);  //true

int a1 = 10;
double d1 = 10.0d;
System.out.println(a1==d1);  //true

int a1 = 10;
char e1 = 10;
System.out.println(a1==e1);  //true

可以看到,在基本数据类型的范围内,不同数据类型也是可以直接比较的

如果比较的是基本数据类型,就是判断两个保存的数据是否相同(不一定类型相同)

1.2 引用数据类型

这里先写一个Student类,用于参考

public class Student {
    public String name;
    public int age;

    public Student(){}

    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
}

实例化两个Student对象,判断是否相等

Student student1 = new Student("Tom", 18);
Student student2 = new Student("Tom", 18);
System.out.println(student1==student2);  //false

注意,这里出现了示例中的第一个false。可以看到,即使赋的值是相同的,但使用==判断的结果为false,这是因为两个对象在内存中不指向同一地址。

如果比较的是引用类型,就是比较两个变量是否代表同一对象实体,也就是是否指向同一地址

1.3 小结

==是运算符
可以使用在基本数据类型变量和引用数据类型变量中
如果比较的是基本数据类型,就是判断两个保存的数据是否相同,不一定类型相同
如果比较的是引用类型,就是比较两个变量是否代表同一对象实体,也就是是否指向同一地址

2. equals

equals()是方法,只能用于引用数据类型

还是使用上面介绍到的Student对象,如果使用equals比较,那么?

Student student1 = new Student("Tom", 18);
Student student2 = new Student("Tom", 18);
System.out.println(student1.equals(student2));  //false

答案还是false,我们可以看一下在此处使用的equals的源码

image-20211107192723195

使用的正是Object中的equals()方法(继承),而Object中的equals()方法也是使用的==进行的比较

Object类中equals()和==的作用相同

诶,部分同学可能想说了,这个equals()和我们平时用的不太一样啊,平时用的equals()好像是用来比较数值的。这里我们拿String类来举例。

String str1 = new String("cun");
String str2 = new String("cun");
System.out.println(str1==str2);  //false
System.out.println(str1.equals(str2));  //true

使用==比较,不出意外是false。而这里使用equals(),得到的结果是true。我们看一下这里的equals()源码(Java8版本)

image-20211107194053016

可以看到,String类中的equals()重写了Object类中的equals(),这里侧重于具体的数值比较(我们日常使用中也是更希望比较具体的数值)。分析一下源码,这里先使用==进行比较,然后判断是否为String的一个示例,判断长度是否相等,最后挨个判断字符是否相等。

源码的大部分程序都比较好理解,有些人比较迷惑这里的强制转换(如下图),既然前一句判断了是否为String类的实例,后一句为什么还要强转?这是因为,在Java中,代码从编写到执行要经历两个过程——编译和执行,在执行时,程序判断了实参是否为String类的实例对象,之后不再需要强转;但是在编译中,即使经历了instanceof判断,编译器还是会始终把传进来的参数当作Object类型,而Object类型是没有value属性的,会直接报错。所以在这里如果不强转,编译都通不过,更不用说执行了。

image-20211107203752851

类似的,我们可以写出Student类中重写的equals()方法。

不过现在因为类使用的非常多,一方面是因为每个类都添加比较繁琐,另一方面我们可能写的可能不够健壮,这里提供两种方式自动提供equals()的重写

IDEA编译器的快捷键“alt + insert”,选择如下图的选项

image-20211107195903003

选择需要添加到equals()的属性

image-20211107200057910

可以看到自动生成的程序

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return age == student.age &&
        Objects.equals(name, student.name);
}

导入lombok包,加入Data注解

@Data
public class Student {
    public String name;
    public int age;

    public Student(){}

    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }
}

可以看到重写了Object类中的equals()方法

image-20211107200459624

3. 总结

	/**
     * ==是运算符,equals是方法
     * 1. ==
     *      可以使用在基本数据类型变量和引用数据类型变量中
     *      如果比较的是基本数据类型,就是判断两个保存的数据是否相同,不一定类型相同
     *      如果比较的是引用类型,就是比较两个变量是否代表同一对象实体,也就是是否指向同一地址
     *
     * 2. equals
     *      只能适用于引用数据类型
     *      Object类中equals()和==的作用相同
     *      像String、Data、File、包装类等中的equals都是重写了Object类中的equals()方法,比较的是实体内容是否相同
     */

到此这篇关于Java中==和equals()的区别的文章就介绍到这了,更多相关Java ==和equals()区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringMVC中@Valid不起效BindingResult读取不到Error信息

    SpringMVC中@Valid不起效BindingResult读取不到Error信息

    在写SpringMVC项目时,由于要对表单数据进行校验,需要使用@Valid进行校验,但是在进行数据校验时,BindingResult对象无法拦截非法表单数据,result.hasErrors()无论怎么输入都会返回false,本文详细的介绍一下解决方法
    2021-09-09
  • Java用邻接矩阵存储图的示例代码

    Java用邻接矩阵存储图的示例代码

    邻接矩阵通常采用一个一维数组存储图中节点的信息,采用一个二维数组存储图中节点之间的邻接关系。本文将利用Java实现用邻接矩阵存储图,需要的可以参考一下
    2022-06-06
  • 手把手教你SpringBoot过滤器N种注册方式

    手把手教你SpringBoot过滤器N种注册方式

    这篇文章主要介绍了手把手教你SpringBoot过滤器N种注册方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 实例解析Java设计模式编程中的适配器模式使用

    实例解析Java设计模式编程中的适配器模式使用

    本篇文章主要通过实例对适配器模式进行了详解,需要的朋友可以参考下
    2017-04-04
  • 修改xml文件再也不用重启项目mybatis-xmlreload方法

    修改xml文件再也不用重启项目mybatis-xmlreload方法

    这篇文章主要为大家介绍了修改xml文件再也不用重启项目mybatis-xmlreload,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 面试官问如何启动Java 线程

    面试官问如何启动Java 线程

    这篇文章主要介绍了面试官问如何启动Java 线程,Java 的线程创建和启动非常简单,但如果问一个线程是怎么启动起来的往往并不清楚,甚至不知道为什么启动时是调用start(),而不是调用run()方法呢?下面我们就一起进入文章学习这个问题吧
    2021-12-12
  • SpringBoot给类进行赋初值的四种方式

    SpringBoot给类进行赋初值的四种方式

    这篇文章主要介绍了springboot给类进行赋初值的四种方式,并通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-08-08
  • Spring循环依赖的解决方法详解

    Spring循环依赖的解决方法详解

    Spring的解决循环依赖是有前置条件的,要解决循环依赖我们首先要了解Spring Bean对象的创建过程和依赖注入的方式。依赖注入方式,我之前的博客有所分享,大家可以在看本篇文章之前进行一下小小的回顾
    2022-08-08
  • MyBatis中insert操作返回主键的实现方法

    MyBatis中insert操作返回主键的实现方法

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数。这篇文章主要介绍了MyBatis中insert操作返回主键的方法,需要的朋友可以参考下
    2016-09-09
  • 九个动画组图轮播总结全栈数据结构数组链表

    九个动画组图轮播总结全栈数据结构数组链表

    数据结构和算法是密不可分的,两者往往是相辅相成的存在,所以在学习数据结构过程中,不免会遇到各种算法,数据结构常用操作一般为:增删改查。基本上所有的数据结构都是围绕这几个操作进行展开,本文用九张动图来阐述先进后出的数据结构
    2021-08-08

最新评论