“==“和equals的区别是什么

2023-10-30

==:对于基本类型,比较的是值是否相等;对于引用类型,比较的是地址是否相等
equals:比较的是对象是否相等(不能比较基本类型,因为equals是Object超类中的方法,而Object是所有类的父类)

因为 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。
如果你不了解Java只有值传递,请看这篇文章:带你深入理解值传递

==来了

看下面的例子

       String str = new String("zsh");
       String str2 = new String("zsh");
       String str3 = "zsh";
       String str4 = "zsh";
       System.out.println(str3 == str4);
       System.out.println(str == str2);
       System.out.println(str == str3);

结果:
在这里插入图片描述

因为这是引用类型,所以比较的是地址是否相等,另外这也涉及到字符串常量池的概念,字符串常量池是什么呢,我怎么想不起来了呢?

当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。

字符串常量池简单了说就是一块内存空间,减少重复创建字符串所需的时间,更多细节请看我的JVM专栏


分析str3==str4的结果

1、这两个对象没有直接使用new,所以当执行String str3=“zsh”时,字符串常量池中就会被创建一个“zsh”的字符串;
2、当执行到String str4=“zsh”,会先去常量池中查找是否有“zsh”这个字符串,如果有,则将str4也指向这个字符串;否者在常量池中创建该字符串。

那么结果为true,自然就能够明白了。


分析str==str2的结果

这个为false应该也很简单,new两个对象,那么地址肯定不同;


分析str==str3的结果

一个是在字符串常量池中,一个在堆中new的对象,那么地址肯定不同了


在这里插入图片描述
equals来了

       String str = new String("zsh");
       String str2 = new String("zsh");
       String str3 = "zsh";
       String str4 = "zsh";
       System.out.println(str3.equals(str4));
       System.out.println(str.equals(str2));
       System.out.println(str.equals(str3));

在这里插入图片描述
是不是感觉很奇怪,明明比较的是引用,为什么都是true呢?这就要分析String的底层代码了

    public boolean equals(Object anObject) {
        if (this == anObject) {	//比较地址是否相等
            return true;
        }//判断是否是String类型,如果不是,还比较个锤子,肯定false呀
        if (anObject instanceof String) {	
        	//转换为本地变量
            String anotherString = (String)anObject;
            //计算字符长度,注意Java字符串末尾没有\0,因为对象都内置的有length方法,所以不需要计算长度。
            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;
    }

核心代码

在这里插入图片描述
这你应该就明白了,String中重写了Object中的equals方法,并重定义了它的功能,把它改成了比较字符串是否相同。

不仅String是这样,包装类也是同样如此

Integer

 public boolean equals(Object obj) {
        if (obj instanceof Integer) {	//判断是否是Integer类型
            return value == ((Integer)obj).intValue();//比较值是否相等
        }
        return false;
    }

Float

public boolean equals(Object obj) {
        return (obj instanceof Float)//是否满足是Float类型和值相等
               && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }

Double

    public boolean equals(Object obj) {
        return (obj instanceof Double)
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
    }

Boolean

public boolean equals(Object obj) {
        if (obj instanceof Boolean) {
            return value == ((Boolean)obj).booleanValue();
        }
        return false;
    }

Character

public final boolean equals(Object obj) {
            return (this == obj);
        }

Long

public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

Boolean

public boolean equals(Object obj) {
        if (obj instanceof Boolean) {
            return value == ((Boolean)obj).booleanValue();
        }
        return false;
    }

包装类全部都重写了equals方法,将其的地址比较改为了值比较。


        User user = new User();
        user.setUsername("zsh");
        User user2 = new User();
        user2.setUsername("zsh");
        System.out.println(user.equals(user2));

结果:false

这个结果应该都在大家的意料之中,User类没重写equals方法,自然就按照地址比较了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“==“和equals的区别是什么 的相关文章

  • 在 JTable 中使用自定义 TablecellRenderer

    我是 Java 新手 我创建了一个JTable 就是这样addRow当我尝试向表中添加一行时 该方法有效 private void addTableRow String type String name String rank String
  • JDT - 尝试更改类型的超类。我不知道超级类的限定名称

    我有一个程序 除其他任务外 还必须使用 JDT 更改某些类的超类 我有两个字符串 其中包含要交换的超类的限定名称 例如 org example John 和 org example Smith 并且我正在解析整个 AST 搜索扩展这些类的类
  • 如何在 Java 中验证从 Azure AD B2C 生成的 JWT 令牌?

    我正在寻找 Java 代码示例来验证 Azure AD B2C 令牌 我们可以使用哪些依赖项 所有 JWT 令牌的 JWT 令牌验证步骤或代码是否相同还是会有所不同 我们的项目中没有使用 Spring Security 有大量的图书馆her
  • 从字符串中删除多个子字符串 - Java

    我需要从给定字符串中删除多个子字符串 例子 String exclude one two three String input if we add one and two we get three 我希望我的程序从输入字符串中删除所有出现的
  • Spring批量写入器限制

    我正在工作 Spring Batch 项目 从数据库读取记录然后写入rabbitmq 然后发送到HTTP消息网关 网关有150TPS我需要将我的应用程序限制为 150TPS 有没有办法带弹簧批的油门或者还有其他更好的方法吗 你能行的 在 S
  • 打印数组时出错

    我得到这个代码 import java util import java io public class Oblig3A public static void main String args OrdAnalyse O new OrdAna
  • LibGDX 闪烁

    我已经使用 LibGDX UI 设置来启动一个项目 我在实现 ApplicationListener 中唯一拥有的是 public void create setScreen new LoadingScreen this 这应该会触发 Lo
  • Java 7 中新的 JNLP 缺少项目警告是怎么回事?

    从 Java 6 切换到 Java 7 后 我的 JNLP 仍然工作正常 但它现在抛出一系列如下错误 Missing Application Name manifest attribute for http blah com app jar
  • 如何使用jdbc驱动编写事务?

    我想使用 jdbc 编写一个事务java 我尝试过这个简单的交易 BEGIN TRANSACTION NL GO NL UPDATE table SET col test where id 1010 NL GO NL COMMIT 我尝试过
  • SQLiteAssetHelper 甚至在从资产文件夹复制数据库之前就导致立即崩溃

    https github com jgilfelt android sqlite asset helper https github com jgilfelt android sqlite asset helper 我要从SQLiteOpe
  • Spring Boot - 如何在开发过程中禁用@Cacheable?

    我正在寻找两件事 如何在开发过程中使用 Spring boot dev 配置文件禁用所有缓存 application properties 中似乎没有通用设置可以将其全部关闭 最简单的方法是什么 如何禁用特定方法的缓存 我尝试像这样使用 S
  • 使用mapstruct映射不同类型列表的元素

    我们正在映射一个对象 该对象具有一个对象列表 这些对象都实现了父接口 但可能具有不同的实现 但当我们映射列表时 似乎只有来自 ParentClass 的值被映射 而不是来自子类的值 但直接映射子进程就可以了 public class Par
  • Spark java:如何处理多部分/表单数据输入?

    我在用spark http sparkjava com 开发网络应用程序 当我想上传文件时出现问题 public final class SparkTesting public static void main final String a
  • 如何在 iText 7 中创建页面大小不等的文档

    如何在 iText 7 中创建页面大小不等的文档 iText7 可以吗 在iText5中 我使用document setPageSize and document newPage 如果您通过高级 API 添加内容 Document add
  • 如何在 Spring GCP 中订阅多个 Google PubSub 项目?

    我想在 Spring Boot 应用程序中订阅多个 Google Cloud PubSub 项目 阅读完相关问题后如何使用 Spring Cloud 在一个 Spring Boot 应用程序中连接 配置两个 pubsub gcp 项目 ht
  • Maven编译错误:包不存在

    我正在尝试向现有企业项目添加 Maven 支持 这是一个多模块项目 前 2 个模块编译和打包没有问题 但我面临编译错误 我尝试在多个模块中使用相同的依赖项 我的结构是 gt parent gt pom xml gt module 1 gt
  • 如何在 VSCode 中热重载 Tomcat 服务器

    我正在从 Eclipse IDE VSCode 分别用于编码 Java servlet 和 HTML CSS JS 网页 迁移到仅使用 Visual Studio Code 因为它的轻量级 我为 VSCode 安装了几个 Java 扩展 R
  • 带有客户端认证连接的 HTTP 客户端的 SOAP 请求超时异常

    我正在尝试点击具有客户端认证的网址并生成密钥 keytool genkey alias server keyalg RSA keystore example jks validity 10950 和密钥存储 keytool import t
  • 如何在 logback 中启动时滚动日志文件

    我想配置 logback 来执行以下操作 记录到文件 当文件达到 50MB 时滚动文件 仅保留 7 天的日志 启动时始终生成一个新文件 滚动 除了最后一项 启动卷 外 我一切都正常 有谁知道如何实现这一目标 这是配置
  • Encog:BasicNetwork:无需预先构建数据集的在线学习

    我正在尝试使用 encog 库作为强化学习问题的函数逼近器 更准确地说 我正在尝试启动并运行多层感知器 BasicNetwork 由于我的代理将根据我选择的任何 RL 算法以某种方式探索世界 因此我无法预先构建任何 BasicNeuralD

随机推荐

  • windows C++ 获取CPU ID

    网上找到了相关代码 但是其中用了嵌入式汇编 只能在win32位下编译运行 根据其他网络资料进行了修改 可以在x64下编译运行 原版资料见链接 链接 link 修改后的代码为 include stdafx h include GetCPUId
  • 【转载】数据库操作系统——Visual FoxPro 6.0安装步骤

    转载地址 https blog csdn net panrenlong article details 82289978 utm medium distribute pc relevant none task blog BlogCommen
  • 如何在DAYU200上安装浏览器-基于OpenHarmony 3.1 Release版本

    1 前言 终于 OpenHarmony有自己的浏览器应用了 可以查看视频演示 先看下效果 打开某宝 可以扫码登录 2 安装教程 2 1 DAYU200升级最新的 3 1Release版本固件 升级教程 https www bilibili
  • Dva系列:connect与@connect的使用(一)

    前言 在刚开始使用Dva的时候 写好models 通过connect进行仓库与组件的链接的时候怎么不是很理解 翻译官方文档也没有明确的解释 提示 以下是本篇文章正文内容 下面案例可供参考 一 connect的用来干什么 connect用来链
  • (微服务多模块)Springboot+Security+Redis+JWT 仅需一招

    小编在开发阶段发现 在现在众多文章中的教程里 虽然有许许多多的Springboot Security Redis JWT 但是那些教程基本的运行环境都在单个项目单个模块中进行开发和测试的 这使得小编在实际的开发过程中 不能Ctrl C an
  • ionic工程报错->Current working directory is not a Cordova-based project的解决

    构建ionic工程出错 奇怪了哎 代码没有动啊 于是重新拉取一份代码 构建发现可以的 于是用比较工具查看 原来是误删了工程目录下的www文件夹导致不能识别 把它恢复就好啦
  • windows下安装gmp库+Dev c++

    需要的三个安装文件 1 Dev c 安装文件 链接 https pan baidu com s 18us8SEEh82zzMvtAeJDedA pwd 1zgo 提取码 1zgo 2 gmp库文件 链接 https pan baidu co
  • 通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明

    因为项目需要 想使用spring的注解方法的AOP切面编程 在xml配置文件中加入
  • 图片自动填充单元格_教你两个word技巧,快速填充文本,插入表格不变形

    许多人说 Word没有什么用 只是一个打字工具 因此长期以来 Word是最被忽视的办公软件之一 觉得自己没必要学习这个软件 从而放弃了学习 但事实却并非如此 在Word看似 简单 的外表下 隐藏着海量的功能和技巧 但很多人其实只会了Word
  • SJTU括号栈配对(OJ599)

    题目源自SJTU OJ 1599 模拟一个括号栈 其元素是三种括号 给出长为n的操作序列 按序列要求完成以下几种操作 push pop 栈空则忽略此操作 输出栈顶元素 栈空则忽略此操作 询问当前括号是否匹配 栈空则认为匹配 Input Fo
  • python爬虫利器:user agent switcher

    一 推荐理由 方便 相比于在浏览器中右键检查 再将浏览器设置成手机端 如下图 user agent switcher给我们带来更多的是方便 一次设置好 就不怕每次麻烦的右键检查 设置成手机端的重复性操作了 这对于python爬虫算是一个比较
  • Keil uVision5开发环境搭建(MDK 5)

    1 下载并安装 MDK作为STM32常用的IDE 其他还有IAR等等 在学习STM32F103的过程中 我之所以选择MDK 是因为KEIL5可以完美兼容KEIL4 与之前的版本相比 最大的区别在于器件 Software Packs 与编译器
  • VS2017+cmake+DCMTK编译安装

    转载自嗯哇创作https blog csdn net chaoenhu article details 78200274 Visual Studio 2015 cmake编译安装MD版的DCMTK 一 编译环境 本文的编译机器是Window
  • 判断字符串类型以及对比

  • R语言数据处理:tidyr包学习

    文章目录 前言 1 gather 函数 2 spread 函数 3 unite 函数 4 separate 函数 5 缺失值处理 总结 前言 在R语言中 tidyr包的应用 tidyr主要提供了一个类似Excel中数据透视表 pivotta
  • git远程连接全流程

    查看文件状态 git status 把文件提交到暂存区 git add 提交文件 命令形式 git commit m 注释内容 连接到远程仓库 这里的origin是远端名称 一般默认都是origin 后面的地址是仓库路径 git remot
  • office2022最新版本Microsoft 365

    office2022正式版是微软即将发布的全新的office版本 office2022正式版将于 2021 年下半年发布 适用于 Windows 和 macOS 系统 按照惯例 微软每隔三年发布一次新版 Office 所以在2021年下半年
  • KEIL调试正在运行的程序

    问题现象 有时程序跑着跑着就飞了 但此时却没有接仿真器 不能停下来看运行状态 如果重新启动调试 会破坏现场 有没有办法attach到应用程序上调试呢 答案是肯定的 解决措施 在调试选项中 取消以下选择项 Options For Target
  • Oracle练习题(九)

    Oracle练习题 九 1 创建一个存储过程 以员工号为参数 输出该员工的工资 创建存储过程 create or replace procedure print sal n number as val sal emp sal type be
  • “==“和equals的区别是什么

    对于基本类型 比较的是值是否相等 对于引用类型 比较的是地址是否相等 equals 比较的是对象是否相等 不能比较基本类型 因为equals是Object超类中的方法 而Object是所有类的父类 因为 Java 只有值传递 所以 对于 来