Java中有了equals(),为什么还有“==“

这篇具有很好参考价值的文章主要介绍了Java中有了equals(),为什么还有“==“。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景:Java中“一切皆是对象”,为什么还有非对象的“==”?

在Java语言假设我们只进行OOP,所以Java代码都是由一个接着一个的类组成的。那么,对象之间比较,用equals()就可以了。

可为什么“==”在代码随处可见呢?

Java是基于C++的,相比与C++,Java是一种更“纯粹”的面向对象程序设计语言。C++和Java都是混合/杂合型语言。

但是,Java的设计者认为这种杂合性并不像在C++中那么重要。

Java编程思想

要想搞清楚这些,需要先拆解一下:

equals()和“==”的区别

equals():在Java中每个对象都默认继承了Object.equals()方法,equals()用来比较两个对象是否内容相同。默认是通过比较两个对象的引用是否相同来判定。

==是Java语言中的关系操作符之一,用于比较操作数是否相等。

==用于对象时,比较的就是对象的引用是否相同。也就是Object.equals()的默认实现

公众号:的数字化之路Java中什么时候用==,什么时候用equals

上面的介绍中,出现了新词:“操作数”。这个在Java中出现的频次并不高的“操作数”与对象、基本类型是什么关系呢?

操作数与基本类型的关系

操作符作用于操作数,生成一个新值。
几乎所有的操作符只能操作“基本类型”。
例外的操作符是“=”,“==”和“!=”,这些操作符能操作所有的对象(这个令人困惑的点,也是这篇文章出现的原因)。
String类支持“+”和“+=”。如果==用于两个对象,则比较这两个对象的引用,如果相等则表示这两个对象是同一个对象。

Java编程思想

小结:所有的基本类型都是操作数。对象也可以是操作数。实际上在最底层,Java中的数据是通过使用操作符来操作的。也包含比较对象的内容(状态)。

Java已经是更“纯粹”的面向对象语言了,为什么还有基本类型?

什么是“面向对象”?

这个“坑”有点大。要聊“面向对象”,“面向过程”是避不开的。

什么是面向过程?系统是物理世界的映射。物理世界中任何事物都有其生命周期,生命周期按时间推进的特性形成了面向过程。

用面向过程的方式来思考现实世界人与人之间的分工的时候,就会遇到很大的困难。比如,流程的每个节点是分散在不同的角色身上的。用面向过程的方式来思考流程时,不同角色的界限就没有了,他们的职责和权利就会淹没在流程中。如果完全采用面向过程的方式,经常会搞得一团糟,一旦需求有任何变化,就会使得所有人都疲于应对。

什么是面向对象?生命周期中还有另外一个特性,即在事物生命周期推进的过程中,生命周期的主体是不变的,这个事物所有的生命周期活动都作用并积累在该事物的本身,如果把“事物”替换为“对象”,就是一个对象的生命周期活动就是该对象的行为,也就是方法;一个对象行为的结果是该对象的状态,也就是数据。

可见,面向过程和面向对象这是软件世界对物理世界让两种理解,就像“盲人摸🐘”一样。两者既不相同、也不对立,而是各有各的特点,反映的是同一个事物的不同侧面,用一个更恰当的词语来说就是“非一非二”:两者既不是同一个,也不是两个不同的东西,而是同一个事物的两个侧面,不可分割。

如何不可分割呢?

先“拆”:一个生命周期拆分之后,会形成多个子生命周期。也就是说,一个对象拆分之后,会形成多个对象,每个对象都具备自己生命周期的所有活动,这就是对象的拆分。

后“合”:生命周期的拆分,在软件中表达为对象的拆分。拆分之后的合并,则是通过面向过程的代码来串联,形成访问流程,也就是访问生命周期。最终还是完整地完成了原有主体的所有生命周期活动。

先“拆”后“合”的好处:拆分之后,不同的业务人员可以分别关注不同的生命周期,并行地推进用户的访问生命周期;不同的代码人员也可以分别关注不同的生命周期,并行地编写代码,从而提升代码产出的效率,使得不同的代码人员之间不会互相干扰。这就是因为“内聚”而带来的“松耦合”

面向对象思想和语言的出现,使得用对象来模拟这个世界的每个独立生命周期成为了可能,让软件可以更加自然、轻松地模拟现实世界。

上面的解读是不是信息密度太大?来看看ChatGPT3.5的回答:

面向对象,全称是面向对象编程(Object-Oriented, OOP),是一种编程思想。
它主要基于对象的概念,将现实世界中的事物看做是对象,并且通过对象之间的交互来完成任务。
面向对象的面向是指OOP的三大特性:
封装(encapsulation)、
继承(inheritance)、
多态(polymorphism)。

ChatGPT3.5

封装和面向对象的内聚有关系。

继承和多态,更多的是指事物的共性。

封装是指将对象的状态和行为封装在一个单元内,对外部世界隐藏内部的实现细节,只暴露必要的接口。这种做法可以提高代码的可维护性和可复用性,同时也保证了数据的安全性。 

继承是指一个类可以从另一个类中继承属性和方法,并且可以在此基础上扩展自己的功能。继承可以减少代码的重复性,提高代码的复用性。 

多态是指同一个类的不同实例或者不同类之间可以表现出不同的行为,实现方式主要有方法重载和方法覆盖等。多态可以增强程序的灵活性和扩展性,让代码更具有可读性和可维护性。 因此,面向对象的“面向”是指在OOP中,封装、继承和多态等特性的应用和实现。

ChatGPT3.5

总结一下,OOP是“是对一个主体活动生命周期的拆解策略,通过一个个对象来封装对象在过程中不同活动时的行为和状态(数据),通过行为和数据的内聚,来实现构建更大的软件规模和提升研发效率的效果” 。

所以,上面的问题实际是在问:“基本类型”如何提升了软件研发效率?

基本类型”如何提升了软件研发效率?

软件系统的性能维度

OOP的理念很好,支持OOP的语言也很多,要是基于OOP思想使用Java语言开发出来的系统运行慢或太消耗资源,就无法商用更无法普及。

因此 ,在程序设计中经常用到一系列类型,它们需要特殊对待。可以把这引起类型想像成“基本类型”。之所以特殊对待,是因为new将对象存储在“堆【Heap】”里,故用new创建一个对象---特别是小的、简单的变更,往往不是很高效。

因此对于这些类型,Java采用与C和C++相同的办法。也就是,不用new来创建变量,而是创建一个并非是引用的“自动”变量。这个变量直接存储“值”,并存于“栈【Stack】”中,因此更加高效。

以Java语言为例:JVM虚拟机运行时数据区

Java中有了equals(),为什么还有“==“

Java对象的一个行为(方法)执行时,数据在JVM中的存放情况:

Java中有了equals(),为什么还有“==“

Java中有了equals(),为什么还有“==“

软件系统的规模提升维度

可读性、可理解性不高,这个软件的可维护性就不好。一个维护困难的系统必然会慢慢“腐烂”掉,表现出来的就是“改不动了”。

OOP再好,要是代码的可读性和可理解性不好,对初学者不友好,会导致学习门槛高,上手困难,也会间接影响这门语言的普及。用的人少了,生态就难以建立。没有生态,这门语言会慢慢沦落为一个小众的“玩具”语言。

可读性、可理解性:Don't make me think

同样的加减乘除,基于基本类型的代码:

int i=1+1;int j=i-1;int k=i*j;int h=k/2;

同样的加减乘除,基于对象行为的代码:​​​​​​​

BigDecimal oData1 = new BigDecimal("20.120");BigDecimal oData2 = new BigDecimal("20.111");BigDecimal addResult = oData1.add(oData2);BigDecimal subtractResult = oData1.subtract(oData2);BigDecimal multiplyResult = oData1.multiply(oData2);BigDecimal divideResult = oData1.divide(oData2, 3, RoundingMode.HALF_UP);

如上,那种代码的可读性、可理解性更好, 不言自明。

小结:

面向对象与“==”解决了软件开发过程中不同层面的问题。用一个更恰当的词语来说就是“非一非二”:两者既不是同一个,也不是两个不同的东西,而是同一个事物的两个侧面。

面向对象是对一个主体生命周期的拆解策略,通过一个个对象的一层层封装来实现构建更大的软件规模和提升研发效率的效果。正所谓“诚以兵虽众多。而层层管辖。分数既明。则如身使臂。如臂使指。左右运掉。仍如一人。”

"=="操作符是具体代码层面的。在这个层面,重点要考虑的是性能、效率、易用性、可读性、可理解性。+、-、*、/、=、== 是跨语言和种族的,用起来自然而言,当然是首选了。

另外,就Java语言而言,支持OOP语言的很多,在做取舍时肯定是演化优于一步到位:先火了再说。那就怎么方便、怎么能快速占领市场就怎么来了。文章来源地址https://www.toymoban.com/news/detail-419595.html

到了这里,关于Java中有了equals(),为什么还有“==“的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 有了MySQL,为什么还要有NoSQL

        🏆今日学习目标: 🍀MySQL和NoSQL的区别 ✅ 创作者 :林在闪闪发光 ⏰预计时间:30分钟 🎉个人主页:林在闪闪发光的个人主页  🍁林在闪闪发光的个人社区,欢迎你的加入: 林在闪闪发光的社区 目录 noSQL的大概意思 理论支撑 为什么需要NoSQL 为什么NoSQL有处理超大规模

    2023年04月20日
    浏览(75)
  • 为什么有了 HTTP 还要 RPC

    哈喽大家好,我是咸鱼 随着互联网技术的发展,分布式架构越来越被人们所采用。在分布式架构下, 为了实现复杂的业务逻辑,应用程序需要分布式通信实现远程调用 而这时候就需要一种协议来支持远程过程调用,以便实现不同应用程序之间的数据交换和信息传递。其中常

    2024年02月05日
    浏览(48)
  • 有了Spring为什么还需要SpringBoot呢

    目录 一、Spring缺点分析 二、什么是Spring Boot 三、Spring Boot的核心功能 3.1 起步依赖 3.2 自动装配 1. 配置文件和依赖太多了!!! spring是一个非常优秀的轻量级框架,以IOC(控制反转)和AOP(面向切面)为思想内核,极大简化了JAVA企业级项目的开发。虽然Spring的组件代码是轻

    2024年02月08日
    浏览(50)
  • 有了NULL,为什么C++还需要nullptr?

    目录 1.引言 2.类型安全 3.函数重载 4.代码清晰性 5.示例 6.总结 在C++编程中,nullptr是一个类型安全的空指针常量,自C++11起被引入。然而,在此之前,程序员们通常使用NULL或0来表示空指针。那么,为什么有了NULL之后,C++还需要引入nullptr呢?本文将从类型安全、函数重载和代

    2024年02月21日
    浏览(50)
  • 为什么有了HTTP,还需要WebSocket协议?

    目录 WebSocket是什么? WebSocket怎样建立连接? WebSocket的实际用途 WebSocket 与 HTTP 的选择 HTTP 是基于 TCP协议 的,同一时间里,客户端和服务器只能有一方主动发数据,是 半双工通信 。 通常,打开某个网页,我们每点击一次网页上的某个选项,前端就会发送一次HTTP请求,网站

    2024年02月11日
    浏览(47)
  • 面试官:为什么有了sleep还需要wait?

    对于线程执行最大的问题就是随机调度,抢占式执行,对于程序猿来讲,是不喜欢这种随机性的,程序猿喜欢确定的东西,于是就有了一些方法,可以控制线程之间的执行顺序,虽然线程在内核里调度是随机的,但我们可以通过一些 api 让线程主动阻塞等待,主动放弃 CPU 给其

    2024年02月05日
    浏览(53)
  • 为什么有了IP地址,还需要MAC地址呢?

    不知道大家有没有困惑:为什么有了IP地址,还需要MAC地址呢? 他们之间到底有什么联系?又有什么区别?是不是有一个是多余的? 流言传到了“IP地址”和“MAC地址”的耳朵里,他俩也非常苦恼,今天文档君把话筒递给他们,看看他们怎么说?     PART   0 1   MACIP的自白

    2024年02月06日
    浏览(53)
  • 指定了ip为什么还有自动配置ipv4?

    刚买了一天双网卡的主机,插上网线配置上网地址,发现指定了ip为什么还有自动配置ipv4? 将研究发现 应该是电脑启用了自动配置IPv4功能,导致了固定IP无法分配给电脑,尝试用命令关闭自动配置IPv4 功能:以管理员身份运行cmd.exe输入: netsh winsock reset catalog 回车输入: net

    2024年02月03日
    浏览(58)
  • 为什么 Microsoft Office 365 那么贵,还有那么多人用Microsoft 365?

    随着数字化办公的普及,越来越多的人开始使用各种办公软件来提高工作效率和便捷性。而Microsoft 365作为全球领先的办公软件套件,拥有着丰富的功能和服务,深受全球用户的欢迎。下面将详细介绍Microsoft 365的功能、版本、软件和适用人群等信息。 Office 365 直装版:https:/

    2024年02月05日
    浏览(59)
  • Spring和IDEA都不推荐用的@Autowired注解,为什么还有那么多人用?

    @Autowired的默认装配 我们都知道在spring中@Autowired注解,是用来自动装配对象的。通常,我们在项目中是这样用的: 没错,这样是能够装配成功的,因为默认情况下spring是按照类型装配的,也就是我们所说的byType方式。 此外,@Autowired注解的required参数默认是true,表示开启自动

    2023年04月18日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包