Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >== 和 equals 的区别是什么?

== 和 equals 的区别是什么?

作者头像
Breeze.
发布于 2022-04-24 05:59:54
发布于 2022-04-24 05:59:54
2.1K08
代码可运行
举报
运行总次数:8
代码可运行
在编写代码的时候我们经常会使用 equals 和 == 来判断两个对象是否相等,那么两者有什么区别呢,主要有以下几点区别:
  1. 首先的区别是,equals 是方法,而 == 是操作符;
  2. 对于基本类型的变量来说(如 short、 int、 long、 float、 double),只能使用 == ,因为这些基本类型的变量没有 equals 方法。对于基本类型变量的比较,使用 == 比较, 一般比较的是它们的值
  3. 对于引用类型的变量来说(例如 String 类)才有 equals 方法,因为 String 继承了 Object 类, equals 是 Object 类的通用方法。对于该类型对象的比较,默认情况下,也就是没有复写 Object 类的 equals 方法,使用 == 和 equals 比较是一样效果的,都是比较的是它们在内存中的存放地址。但是对于某些类来说,为了满足自身业务需求,可能存在 equals 方法被复写的情况,这时使用 equals 方法比较需要看具体的情况,例如 String 类,使用 equals 方法会比较它们的值

对于上述第三点理解起来可能有点复杂,因为这里 equals 方法比较需要分两种情况来讨论,一种情况是该方法没有被重写,另外一种是该方法被重写。

  • 对于 equals 方法没有被重写的情况。如果类没有重写该方法,那么默认使用的就是 Object 类的方法,以下是 Object 类的 equals 方法:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  public boolean equals(Object obj) {
      return (this == obj);
  }

从源码可以看出,里面使用的就是 == 比较,所以这种情况下比较的就是它们在内存中的存放地址。

  • 对于 equals 方法被重写的情况。以 String 类为例,以下是 String 类中的 equals 方法:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @Override 
  public boolean equals(Object other) {
      if (other == this) {
        return true;
  }
  if (other instanceof String) {
      String s = (String)other;
      int count = this.count;
      if (s.count != count) {
          return false;
      }
      if (hashCode() != s.hashCode()) {
          return false;
      }
      char[] value1 = value;
      int offset1 = offset;
      char[] value2 = s.value;
      int offset2 = s.offset;
      for (int end = offset1 + count; offset1 < end; ) {
          if (value1[offset1] != value2[offset2]) {
              return false;
          }
          offset1++;
          offset2++;
      }
      return true;
  } else {
      return false;
  }
}

从源码可以看出, String 类复写了 equals 方法,当使用 == 比较内存的存放地址不相等时,接下来会比较字符串的内容是否 相等,所以 String 类中的 equals 方法会比较两者的字符串内容是否一样。我们来看看下面的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    String a = "Hello World";
    String b = new String("Hello World");
    String c = b; //引用传递
    System.out.println("a == b:" + a == b);             //false
    System.out.println("b == c:" + b == c);             //true
    System.out.println("a == c:" + a == c);             //false
    System.out.println("a.equals(b):" + a.equals(b));   //true
    System.out.println("b.equals(c):" + b.equals(c));   //true
    System.out.println("a.equals(c):" + a.equals(c));   //true

    最终的打印会是:
    a == b:false
    b == c:true
    a == c:false
    a.equals(b):true
    b.equals(c):true
    a.equals(c):true

因为 String b 通过 new 的方式已经开辟了新的堆内存,而 String a = "Hello World" 是存放在常量池里的,两者在 Java 内存里存在放的位置是不同的,所以 a == b 为 false;而 equals 方法当两者存放的内存地址不同时,会比较两者的值,两者的值都是 "Hello World" ,所以 a.equals(b) 为 true。

另外请思考一下下方代码的运行结果为什么是 True、false

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Java_epuals {
    public static void main(String[] args) {
        Integer i2 = 10;
        Integer i3 = 10;
        System.out.println(i2 == i3); // true

        Integer i4 = 128;
        Integer i5 = 128;
        System.out.println(i4 == i5); // false
    }
}

对于 i2 和 i3 的比较,因为变量的定义方法是 i2(i3) = 10 它们的变量会置于常量区,两个变量的内存地址相同。

此时 == 返回 true

那么为什么 i4 和 i5 是返回 false 呢?

这是因为 Java 中 integer 范围取值要在-128到+127 (为什么Integer对象范围(-128-127)之间),而我们赋的值是 128 ,此时变量并不在常量区定义。所以两个变量的内存地址不同,== 返回 false

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
equals 和 == 到底有什么区别?
Java 中的 equals 和 == 对于不同的数据类型有不同的表现,话不多少,看演示。 对于基本数据类型 对于基本数据类型来说,只能用 ==,所以毫无疑问,这里是用来判断两个基本数据类型的值是否一致。 对于基本数据类型包装类 先来看看这种创建对象的方式: public class Demo { public static void main(String[] args) { Integer i1 = new Integer(100); Integer i2 =
一份执着✘
2018/06/04
7030
面试题系列第3篇:Integer等号判断的内幕,你可能不知道?
面试过程中关于Integer的比较“==”的问题内容层出不穷,但无论怎么变化,只要了解了其中的底层原理,马上就可以得出答案,再也不用死记硬背考题了。
程序新视界
2020/08/28
6620
面试题系列第3篇:Integer等号判断的内幕,你可能不知道?
java基础面试题
Java 虚拟机是运行字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,给出相同的结果。
Vincent-yuan
2021/02/25
4410
java基础面试题
java 常量池和运行时常量池_常量池在jvm的哪个部分
一直在《深入理解JVM》对常量池只有一个浅薄的了解,之前也遇到过这种题目,今天还是要挑出来进行一次全方位的了解。
全栈程序员站长
2022/09/30
4640
java 常量池和运行时常量池_常量池在jvm的哪个部分
你不知道的 equals 和 ==
i1 == i2 和 i1.equals(i2) 这两个都是 true,大多数人应该可以答对。后面的 i3 == i4 和 i3.equals(i4) 估计就有不少人搞不清了。
Wizey
2018/08/30
5260
深入解析==与equals()区别
相信大家一定在很多地方多看到过==与equals()的区别,也把区别讲的很详细,每次记住了,很快又会变得模糊不清。 这时就需要从原理深入剖析,一招制敌!
公众号 IT老哥
2020/09/16
3700
深入解析==与equals()区别
Java 自动装箱与拆箱的实现原理
什么是自动装箱和拆箱 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte, short, char, int, long, float, double 和 boolean 对应的封装类为Byte, Short, Character, Integer, Long, Float, Double, B
java404
2018/05/18
1.8K0
Java八种包装类、常量池
还记得 Java八种基本数据类型及对应包装类、四种引用类型吗?如果忘记可以到这里重温复习Java数据类型(八种基本数据类型 + 四种引用类型)、数据类型转换
寻求出路的程序媛
2024/04/27
2480
Java八种包装类、常量池
JVM解读-方法区
方法区,Method Area, 对于习惯在HotSpot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价,仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。对于其他虚拟机(如BEA JRockit、IBM J9等)来说是不存在永久代的概念的。
高广超
2018/12/12
9280
Java常量池理解与总结
用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。什么是常量
九州暮云
2019/08/21
6160
Integer、new Integer() 和 int 比较的面试题
https://www.cnblogs.com/cxxjohnson/p/10504840.html
java思维导图
2019/08/23
8270
傻傻分不清?Integer、new Integer() 和 int 的面试题
1、Integer 是 int 的包装类,int 则是 java 的一种基本数据类型 2、Integer 变量必须实例化后才能使用,而int变量不需要 3、Integer 实际是对象的引用,当new一个 Integer时,实际上是生成一个指针指向此对象;而 int 则是直接存储数据值 4、Integer的默认值是null,int的默认值是0
Java技术栈
2019/10/22
3910
java之学习Integer类相关面试题
相关知识 integer类的equal方法 public boolean equals(Object obj)比较此对象与指定对象。当且仅当参数不为 null,并且是一个与该对象包含相同 int 值的 Integer 对象时,结果为 true。 自动装箱 自动装箱在byte取之范围之内(-128~127),则不创建对象在常量池中获取,如果超出byte范围则创建对象 package com.ifenx8.study.array; public class Demo_Integer2 { /**
吾爱乐享
2018/07/13
2850
String 类和常量池
尽量避免多个字符串拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer。
happyJared
2019/07/28
5600
详解 Java 中的自动装箱与拆箱
原文链接:https://www.cnblogs.com/wang-yaz/p/8516151.html
cxuan
2020/12/21
8180
详解 Java 中的自动装箱与拆箱
String类和常量池内存分析例子以及8种基本类型[通俗易懂]
该篇例子几乎涵盖了目前所有能解决的类型,以一种通俗的语言讲解出来。当然如果JVM内存基本问题不太会可以看这里:JVM内存的基本问题
全栈程序员站长
2022/09/30
2640
Java学习笔记--常用类及其常用方法、JDK5新特性、正则表达式介绍
object类String类其他类常用方法StringBuffer类JDK5新特性正则表达式Random类其他类常用方法Calendar类
用户7886150
2020/12/12
5590
深入理解 Java 基本数据类型
一般情况下,定义了某数据类型的变量,就不能再随意转换。但是 JAVA 允许用户对基本类型做有限度的类型转换。
静默虚空
2019/05/25
1.1K0
【Java面试题系列】:Java基础知识面试题,看这一篇就够了
参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定要不要继续此次面试,如果答的不好,有些公司可能会直接说“技术经理或者总监在忙,你先回去等通知吧”,有些公司可能会继续面试,了解下你的项目经验等情况。
用户5546570
2019/06/06
4960
JVM面试考点—— 值==问题(常量池)
java中基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean。
高广超
2018/12/12
4380
相关推荐
equals 和 == 到底有什么区别?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验