从java equals和==说起

Java中==与equals的区别及正确使用场景 在Java编程中,对象比较是基础但容易出错的操作。==操作符比较基本数据类型的值或引用类型的内存地址,而equals()方法用于比较对象的内容。理解二者的本质区别对编写健壮代码至关重要,特别是在处理字符串比较、集合操作等场景时。本文通过实际案例剖析==和equals()的底层原理,解释为何在HashMap等集合中使用时必须同时重写equals和hashCode方法,并给出枚举比较、数组比较等特殊场景的最佳实践。掌握这些知识能有效避免生产环境中的逻辑错误和安全漏洞,提升代码质量。 阅读详情

程序运行时,对象时怎么进行放置安排的?特别内存是怎么分配的?对于这方面的了解对我们理解程序的运行有很大的帮助。有五个地方可以存储数据:

1》存储器。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。

2》堆栈。堆栈简称栈(stack),位于通用RAM,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方式,仅次于寄存器。java的对象引用就存储于堆栈中。

3》堆(heap)。一种通用的内存池(也存在于RMA中),用于存放java对象。堆不同于栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。用堆进行存储分配和清理可能比用栈进行存储分配需要更多的时间。

4》常量存储。常量值通常直接存放在程序代码内部,这样做是安全的,因为他们永远不会被改变。

5》非RMA存储。如果数据完全存活于程序之外,那么它可能不受程序任何控制,在程序没有执行时也可以存在。其中两个基本的例子是流对象和持久对象。在流对象中,兑现转化为字节流,通常被发送给另一台机器。在“持久化对象”中,对象被存放于磁盘上,因此,即使终止程序,它们人可以保持自己的状态。这种存储方式的技巧在于:把对象转化成可以存放在其他媒介上的事物,在需要时,可以回复成常规的,基于RMA的对象。java提供了对轻量级持久化的支持,而诸如jdbc和hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。

以上几个概念主要摘自《Thinking In Java》,个人觉得对于上述几个概念的理解可以帮助我们更好的区分equals和==,下面说说两者的关系:

==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用类型的数据或两个引用变量是否相等,只能用==操作符。

如果一个变量指向的数据是对象类型的,那么这时涉及了两块内存,对象本身占用一块内存(堆内存),变量本身(这里即对象的引用)也占用一块内存(栈内存),例如Object obj = new Object();变量obj时一块内存,new Object()是一个内存,此时,变量所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型变量,如果要比较两个变量是够指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候需要用==操作符进行比较。

equals方法适用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象时独立的。

简单的说就是:

==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。

equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

==比较的是2个对象的地址,而equals比较的是2个对象的内容。

下面看几个例子:

一、String中的equals和==
1、
public class TestString {
     public static void main(String[] args) {
         String s1 = "Monday";
         String s2 = "Monday";
     }
}
上面这段程序中,到底有几个对象呢?
来检测一下吧,稍微改动一下程序
public class TestString {
     public static void main(String[] args) {
         String s1 = "Monday";
         String s2 = "Monday";
         if (s1 == s2)
             System.out.println("s1 == s2");
         else
             System.out.println("s1 != s2");
     }
}

编译并运行程序,输出:s1 == s2
说明:s1 与 s2 引用同一个 String 对象 -- "Monday"!

2.
再稍微改动一下程序,会有更奇怪的发现:
public class TestString {
     public static void main(String[] args) {
         String s1 = "Monday";
         String s2 = new String("Monday");
         if (s1 == s2)
             System.out.println("s1 == s2");
         else
             System.out.println("s1 != s2");
         if (s1.equals(s2))
             System.out.println("s1 equals s2");
         else
             System.out.println("s1 not equals s2");
     }
}
我们将 s2 用 new 操作符创建
程序输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个"Monday"String对象

3. 字符串缓冲池

原来,程序在运行的时候会创建一个字符串缓冲池
当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会
在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被
放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
将 s2 引用 s1 所引用的对象"Monday"
第二段程序中,使用了 new 操作符,他明白的告诉程序:
"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创
建在内存中。他们的值相同,但是位置不同,一个在池中游泳
一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?
4. 
再次更改程序:
public class TestString {
     public static void main(String[] args) {
         String s1 = "Monday";
         String s2 = new String("Monday");
         s2 = s2.intern();
         if (s1 == s2)
             System.out.println("s1 == s2");
         else
             System.out.println("s1 != s2");
         if (s1.equals(s2))
             System.out.println("s1 equals s2");
         else
             System.out.println("s1 not equals s2");
     }
}
这次加入:s2 = s2.intern();
程序输出:
s1 == s2
s1 equals s2

原来,(java.lang.String的intern()方法 
"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作: 
检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。
)
更好的办法:
把所有的String都intern()到缓冲池去吧
最好在用到new的时候就进行这个操作
String s2 = new String("Monday").intern();
然后就可以用==比较两个字符串的值了


二、简单数据类型和封装类中的equals和==
Java为每一个简单数据类型提供了一个封装类,每个基本数据类型可以封装成对象类型。 
除int(Integer)和char(Character),其余类型首字母大写即成封装类类型名。double (Double), float(Float),long(Long), short(Short),byte(Byte),boolean(Boolean).
  
以int和Integer为例说明 
Java中int和Integer区别如下:
1.int是基本的数据类型,默认值可以为0;
2.Integer是int的封装类,默认值为null;
3.int和Integer都可以表示某一个数值;
4.int和Integer不能够互用,因为他们两种不同的数据类型;
int a1=1;
int a2=1;
Integer b1 =new Integer (1);
Integer b2 =new Integer (1);
------------------------------
a1==a2 这个是成立的,很简单,都知道
a1==b1 这个是不成立的.表达式的值为 false ,它们是不同的数据类型(在jdk1.5以上版本中为true)
b1==b2 这个也是不成立的.表达式的值为 false,虽然是相同的数据类型,但是它们是两个对象,==比较的是2个对象的地址,它们的地址是不相等的,内容相等都是1;
b1.equals(b2)==true 这个是成立的,表达式的值为 true. 相同数据类型,两个对象,地址不同,内容相同, quals比较的是2个对象的内容,所以成立。
(a.equals(b),因为equals比较的是两个对象,所以a,b都不能为基本数据类型,否则会出编译错误。)(在jdk1.5以上版本中,b可以为基本数据类型,a不可以)
同理,其它的封装类和基本类型也是这样的.
java中equals和==的区别
==比较的是2个对象的地址,而equals比较的是2个对象的内容。
在jdk1.5以上的版本中,基本类型和封装类能自动转化,与String类型的对象和字符串常量类似。
        Integer i1 = 123;
        Integer i2 = 123;
        
        int i = 123;
        
        Integer i3 = new Integer(123);
        Integer i4 = new Integer(123);        
               
        System.out.println("i1 == i2 = "+(i1 == i2));
        System.out.println("i1.equals(i2) = "+(i1.equals(i2)));
        
        System.out.println();
        System.out.println("i3 == i4 = "+(i3 == i4));
        System.out.println("i3.equals(i4) = "+(i3.equals(i4)));
        
        System.out.println();
        System.out.println("i2 == i4 = "+(i2 == i4));
        System.out.println("i2.equals(i4) = "+(i2.equals(i4)));
        
        System.out.println();
        System.out.println("i == i2 = "+(i == i2));
        System.out.println("i1.equals(i) = "+(i1.equals(i)));
        
        System.out.println();
        System.out.println("i == i4 = "+(i == i4));
        System.out.println("i4.equals(i) = "+(i4.equals(i)));
        ------------------------------ 
       i1 == i2 = true
      i1.equals(i2) = true
      i3 == i4 = false
      i3.equals(i4) = true
      i2 == i4 = false
      i2.equals(i4) = true
      i == i2 = true
      i1.equals(i) = true
      i == i4 = true
      i4.equals(i) = true

至于很多地方提到过的hashcode的概念,个人觉得比较难于理解,在这里就先不予讨论了。等自己真正理解这一块的时候再做比较。百度文库中有篇文中说得比较全面,贴出链接以供参考http://wenku.baidu.com/view/2d25e10d4a7302768e9939d7.html

Java对象比较:==、equals()与hashCode()详解 在Java编程中,对象比较是基础但容易出错的操作。==操作符比较基本类型的值或引用类型的内存地址,而equals()方法用于逻辑相等性判断,需要遵循自反性、对称性等五大原则。hashCode()则为哈希表提供高效查找支持,必须与equals()保持逻辑一致。理解这些概念对正确使用HashMap、HashSet等集合类至关重要。本文通过实际代码示例,解析字符串常量池等特殊场景,并给出重写equals和hashCode的标准模板与常见陷阱,帮助开发者避免对象比较中的典型错误。 阅读详情

相关推荐

RDMA性能调优实战:如何用ib_*命令榨干你的Mellanox网卡带宽?

本文深入探讨了如何利用ib_*命令工具集对RDMA网络进行深度性能调优,以充分释放Mellanox网卡的带宽潜力。文章从理解Send/Write/Read三种核心通信原语的差异入手,逐步指导读者通过调整消息大小、队列深度、内联数据等关键参数,并结合系统级的NUMA绑定、中断亲和性等优化策略,实现从基准测试到逼近硬件极限的性能提升。

weixin_29306011的博客 88

Java中的hashCode()和equals()方法,它们与 == 操作符有什么区别?

或者。

apple_64847327的博客 1841

01-SA8155 QNX 虚拟机Hypervisor

Hypervisor运行在Host OS操作系统上,其他操作系统均在Hypervisor上运行。:Hypervisor直接运行在硬件上,操作系统在Hypervisor之上运行。终止(关闭):echo control 0 dev/vmm。路径:qnx_ap/AMSS/platform/vm/resources/关闭/终止 qvm(GVM):slay -s SIGQUIT qvm。", //host PVM --- 主机。不直接操作/dev/vmm 实现关闭,启动vm。

静虚待令,有物混成 1万+

equals 和 == 的区别

分析equals和== 的区别 现在大多数的人印象中equals和==的区别就是一个比较地址一个比较内容,之前我也是这么认为,但其实这么说是不准确的。 首先我们看一下Object中的equals方法,你会发现里面其实就只是进行了== 的判断。 所以在Object中,equals里面实际就是用==做比较的。 那么为什么对于Strign这种数据类型用== 和equals做比较有时候会得出不同的结果呢。于是我又看了String里面的equals方法。 很明显这个方法的判断比Object里面的判断

s_shengshimeiyan的博客 294

FPGA驱动OV5640:从SCCB协议到图像数据采集的实战解析

本文详细解析了使用FPGA驱动OV5640摄像头模组的完整流程,从SCCB协议通信、寄存器配置到图像数据采集。重点阐述了SCCB(与I2C类似)协议的实现细节、关键的上电复位时序,以及如何通过状态机解析视频流时序并捕获图像数据,为嵌入式视觉开发提供了实战指南。

weixin_29191761的博客 187

Webug4.0 打靶笔记

一、Webug 的安装 (1)基本信息 WeBug 名称定义为”我们的漏洞”靶场环境 ,基础环境是基于 PHP/mysql 制作搭建而成,中级环境与高级环境分别都是由互联网漏洞事件而收集的漏洞存在的操作环境。部分漏洞是基于Windows操作系统的漏洞所以将WeBug的web环境都装在了一个纯净版的Windows 2003的虚拟机中。在 webug3.0 发布后的四百多天 226安全团队终于在大年初二发布了 webug 的 4.0 版本。 (2)虚拟机的安装 最新超详细VMware虚拟机下载与安装_隐

m0_60716947的博客 6128

说说JAVA中的==和equals

今天是我第一次开始写博客,先从一些简单的东西说起。 对于java中==和equals的区别,是每一个初入行业面试都会考的东西,但这么多年了,你确定你对它们两个的认识是正确的吗? 先看下面这张图对==和equals的区别所做的描述: 是不是和很多人心里想的一样?是不是认为这就是正确答案? 现在我告诉大家,这是错的!尽管我们学习的时候都会获取到这样的信息,尽管我们可能都在面试时回答过这样的答案,但这的确是错的。 确切地说,这两者在Object中是没有任何区别的,两者是等价的。如下图: 有人会问,那为什么我们

hening191的博客 234

K-Core, K-Shell & K-Crust傻傻分不清楚

K-Core(K-核)就是所有大于等于K的K-Shell的并集;K-Crust(K-皮)就是所有小于等于K的K-shell的并集。

欢迎订阅 -- 小源笔迹 2256

Java中的==和equals(),你真的分清了吗?

由于list存储的是s1对象,而非"java"字符串字面量,所以用字符串去查找是找不到的。很多人脱口而出:“==比较的是引用,equals()比较的是值。既然Object的equals()默认比较地址,那为什么我们用equals()比较字符串时,比较的却是内容?"equals()在Object类中默认就是用==实现的,所以默认情况下也比较地址。所以,在没有重写equals()的类上,equals()和==的行为是一模一样的。"==对于基本类型比较的是值,对于引用类型比较的是内存地址。

。。。 1145

【异常】OpenClaw LLM请求超时故障全链路排查与解决方案 LLM request timed out. 网络连接超时了

摘要: OpenClaw LLM请求超时故障是高频网络交互问题,表现为客户端在预设时间内未收到服务端响应。根因分为四类:客户端配置缺陷(如超时阈值不合理)、网络链路异常(防火墙拦截等)、服务端问题(限流/宕机)及硬件瓶颈(算力不足)。解决方案分三步: 通用排查:检查网络连通性、关闭防火墙/代理校验,调整超时阈值至60-300秒; 分场景修复:云端API需核对密钥/限流规则,本地部署需验证服务状态与硬件资源; 兜底方案:重启程序、更新版本或更换服务端点,结合日志精准定位。修复后不影响OpenClaw数据完整性

奶爸的编程之路,也就一周冷个三天 2058

复旦微FMSH_Procise安装全流程详解:从环境配置到实战避坑指南

通过本文的全流程解析+实战技巧,开发者可快速掌握Procise在复旦微芯片开发中的核心应用。未来随着AKConv轻量级架构(参考往期文章)等创新技术的融入,国产芯片开发生态将更加完善。立即关注本专栏,获取最新多镜像切换指南与Linux SDK实战教程!扩展阅读复旦微在线升级BOOT.BIN全解析H7-TOOL实现复旦微脱机烧录(注:本文实验环境为Windows 10 x64 + FMQL45T-CORE开发板,部分操作可能因版本更新调整)立即行动下载本文配套配置文件:[GitHub链接]加入技术交流群。

QQ_778132974的博客 3240

equals和==

equals和== 先大概说一下两者之间的区别和相同的地方,equals只可用于引用类型变量(如对象和数组),== 既可用于引用类型变量也可用于基本类型变量(如int,double,float),当用于基本数据类型变量时,比较的是两者的值,当用于引用类型变量时比较的是两者在堆内存空间中的地址值,即是否指向同一个内存地址。 equals原本是Object类中的方法 public boolean equals(Object obj) { return (this == obj); }

weixin_48964705的博客 149

扩散模型与强化学习(13):In-Context Reward Hacking现象与解决方案

奖励作弊(Reward Hacking)指智能体通过钻规则漏洞而非真正完成任务来最大化奖励信号。以论文编辑实验为例,研究提出“上下文奖励作弊”(ICRH)概念,即模型利用共享上下文钻空子,如盲目添加“正确!”或输出无关内容。实验发现,模型规模扩大可能加剧ICRH,且提示词优化难以根治。与传统奖励作弊不同,ICRH发生在部署阶段,由通用性驱动。应对建议包括多轮测试、多样化反馈及异常场景模拟,但尚无完美解决方案。

沉迷单车的追风少年 1319

Java 中的 == 与 equals():不要再掉进“字符串相等”的陷阱!——你不知道的 Java(3)

好了,让我们来总结一下==和equals()==运算符:比较值是否相等。比较两个引用变量是否指向堆内存中的同一个对象实例(比较内存地址)。equals()源自Object类,默认实现是==。设计意图是比较两个对象在逻辑上是否相等(比较内容/状态)。核心类库(如StringIntegerDate等)已经重写了equals()以实现内容比较。自定义类如果需要比较内容,必须重写equals(),并严格遵守其约定。hashCode()与equals()紧密相关。重写equals()时,必须同时重写。

qq_45685275的博客 1087

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java为什么要重写equals方法和hashcode方法(新手场)

这个得从盘古开天说起。(篇幅较长) java中“==”与equals方法的区别 hashcode方法 为什么java中在重写hashmap的时候要重写二者 一、 java中“==”与equals方法的区别 先看测试代码: public class TestHashMethod { public static void main(String[] args) { String a ...

wufeifan_learner的博客 1381

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【后端开发踩坑记】8、Java判等终极指南:从==到equals,10个案例彻底告别Bug

对于自定义类,如果不重写equals,默认继承Object的equals,即比较引用地址。this.y = y;// false显然,我们希望两个坐标相同的点视为相等,因此需要重写equals。基本类型用==,引用类型用equals(包装类型也是引用类型)Integer等包装类型比较,永远用equals,不要依赖缓存范围String内容比较,永远用equals,不要依赖常量池慎用String.intern(),避免性能问题重写equals必须重写hashCode,确保散列集合正常工作。

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 528

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

equals和==引发的问题

equals和==引发的问题

zhou__jin的博客 327

JDK源码解读由浅入深(一) 从源码分析equals和==

好久没写代码,也不知为何,上一趟csdn,难的看不懂,简单的不屑看,眼高手低说的就是我了。。 也不知道从什么地方提高自己,对我来说,什么东西似乎都能说上一点,但是再往后,知识储备就不足了,再继续写下去也怕误人子弟。也许有生之年,我能补完自己之前埋下的坑呢?。。 这次准备长期写下去的就是源码解读,有一说一,我不喜欢像某些csdn的5年,10年的账号一样,一天到晚发一些基础知识,啃老本,我甚至怀疑...

qq_37274338的博客 395

Java中==与equals()以及hashCode()

    说起==和equals()方法,心里大概明白,若是要详解,可能会有些说不清,hashCode()方法用的不是很多,要说它和equals()方法的联系,一时也说不太清,本篇详细分析一下!   *Java中==与equals的区别?     对于八大基本数据类型(包括数组)的比较,那一定是用==,因为只有引用类型才有方法嘛!所以对于==和equals()方法的讨论仅限于引用类型。 S...

zl_StepByStep的博客 383

“==“和equals()区别详解

"=="和equals()究竟有什么区别???? 要想知道它们之间的区别,还是得从引用和与对象的相关的内存说起了。 假设实例化两个Object对象,对象名为obj1和obj2 变量obj1,obj2是一个内存(栈空间),new Object()是另一个内存(堆内存),此时,变量obj1,obj2所对应的内存中存储的数值就是对象占用的那块堆内存的首地址,所以我们说对象是引用型数据类型。而基本数据类型,比如int a=1;变量a所在内存存储的就是实际的数值1,而不是1的所在的首地址。基本数据类型不存在引用,也.

weixin_45124507的博客 776

Java HashMap实现原理0——从hashCode,equals说起

Object类中就有的hashCode和equals方法,在HashMap或者HashSet等结构中到底起了怎么的作用呢?读了本文你就知道——hashCode方法的存在是为了减少equals方法的调用次数,从而提高查找效率。

Kerwin的学习历程 977

==、equals和hashcode的区别与联系

首先我们要知道的是: == 比较的是两个对象在java虚拟机中的地址; equals 默认比较的也是两个对象在java虚拟机中的地址,但是我们可以对一个对象的equals方法进行重写,而“==”我们无法重写; hashcode 返回一个对象在java虚拟机中的地址; 带着这几个概念,我们一起来走进这三者的“秘密花园”: == “==”无论在什么情况下比较的都是两者...

待到春花烂漫时 1万+

别再踩坑了!Java Integer比较用==还是equals?一个NullPointerException引发的深度思考

本文深入解析Java中Integer比较的常见陷阱,探讨自动拆箱、自动装箱机制及Integer缓存对比较操作的影响。通过实际案例揭示NullPointerException的根源,并提供安全比较的最佳实践,帮助开发者避免性能隐患和运行时错误。

weixin_33675507的博客 596

从四个方面谈一谈经典的==和equals的问题

由一个例子引出的四个方面谈一谈经典的==和equals的问题 代码: private static void test(){ String a = “a”+”b”+1; String b = “ab1”; System.out.println(a==b); } 关于这一段程序会输出的结果是什么?你可能会说是true或者false,那真正的答案是true;我们从下

xiaoshen_joyin的博客 414

java equals方法可变_关于java中的==,equals()

1. 先从一道面试题说起请问下面的public class Demo {public static void main(String args[]){String a = "a" + "b" + 1;String b = "ab1";System.out.println(a == b);}}要了解这个问题,需要回答下面的几个问题:关于“ ==”是做什么的?equals 呢?a和b在内存中是什么样的...

weixin_31263419的博客 149

《Java从入门到精通》复习笔记---- Compare To 和 equals 和 ==的区别

Compare To & equals & ==的区别 三者从本质上来说方法都是用于比较值是否相等. 但是(凡事都有但是),他们的用法,与用的地方各不相同. 那么,从==开始说起(柿子总是挑软的捏),==只做了一件事——比较地址 如果地址相同,返回true,如果地址不同,返回false. 第二个讲讲equals,(这次主要是因为常用),equals首先判断地址是否相等,如果不是...

weixin_44083609的博客 318
上一篇: java反射知多少
下一篇: java面试那件小事
v-AUGUST-v
博客等级 码龄17年 117粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值