详解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()区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Swing组件文件选择器JFileChooser简单用法示例

    Java Swing组件文件选择器JFileChooser简单用法示例

    这篇文章主要介绍了Java Swing组件文件选择器JFileChooser简单用法,结合实例形式分析了Swing组件中的文件选择器JFileChooser的简单使用方法,需要的朋友可以参考下
    2017-11-11
  • Java学习常用包(类)之java.util包详解

    Java学习常用包(类)之java.util包详解

    这篇文章主要介绍了Java学习常用包(类)之java.util包的相关资料,Java.util包是Java标准类库的重要组成部分,包含集合框架、日期时间类、事件模型、随机数生成器等实用工具类,集合框架提供了多种数据结构和算法,需要的朋友可以参考下
    2024-10-10
  • Java开发微信公众号接收和被动回复普通消息

    Java开发微信公众号接收和被动回复普通消息

    这篇文章主要介绍了Java开发微信公众号接收和被动回复普通消息的相关资料,需要的朋友可以参考下
    2016-01-01
  • Windows同时配置两个jdk环境变量的操作步骤

    Windows同时配置两个jdk环境变量的操作步骤

    Java Development Kit (JDK) 是开发Java应用程序的基础,包含了编译器、调试器以及其他必要的工具,本指南将一步步指导您完成在Windows操作系统上同时配置两个jdk环境变量的操作步骤,需要的朋友可以参考下
    2024-09-09
  • 解决Lombok使用@Builder无法build父类属性的问题

    解决Lombok使用@Builder无法build父类属性的问题

    这篇文章主要介绍了解决Lombok使用@Builder无法build父类属性的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Springboot在IDEA热部署的配置方法

    Springboot在IDEA热部署的配置方法

    这篇文章主要介绍了Springboot在IDEA热部署的配置方法,给大家补充介绍了Intellij IDEA 4种配置热部署的方法,需要的朋友可以参考下
    2018-04-04
  • ThreadLocal内存泄漏常见要点解析

    ThreadLocal内存泄漏常见要点解析

    这篇文章主要介绍了ThreadLocal内存泄漏常见要点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Java接口的本质解析

    Java接口的本质解析

    Java接口是初学者必须经历的基础,但初学之时肯定不会完全懂,温故而知新本篇文章就带你重拾接口全面掌握
    2022-03-03
  • 基于ZooKeeper实现队列源码

    基于ZooKeeper实现队列源码

    这篇文章主要介绍了基于ZooKeeper实现队列源码的相关内容,包括其实现原理和应用场景,以及对队列的简单介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-09-09
  • Java实现数组翻转的实现代码

    Java实现数组翻转的实现代码

    这篇文章主要介绍了Java实现数组翻转的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09

最新评论