Java细节:单等于号、双等于号、三等于号(js中才有)的作用及双等于号和equals(源码)的区别

简介: Java细节:单等于号、双等于号、三等于号(js中才有)的作用及双等于号和equals(源码)的区别

我们在编程时总是会用到=或==,但是等于号都有什么作用呢?下面我们来看一下

(注:下文会提及一点常量池、堆栈,由于本人了解还不是透彻,暂不做解释,日后会做总结,可先点击字面查看理解)


一、单等于号的作用


1.单等于号具有赋值作用


我们在定义变量时,会对变量进行赋值,例如a=3,就是把3赋值给a。

这就是在初始化对象的时候进行赋值。


2.单等于号具有引用对象作用


比如我们写了 a1=a2,表示对象a1指向的内存地址与a2相同,即a1,a2指向同一个对象,这时候a2就引用了a1的地址,起到了传地址的作用。如果改变a2,a1也会相应改变。


二、双等于号的作用


==操作对于 基本数据类型比较的是两个变量的值是否相等 ,对于 引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。


这时我们应该注意到== 具有不严谨的性质 ,即当 == 两边值类型不同的时候,要先进行类型转换,再比较,这时就可能会相等,下面我们看具体情况:


1.如果两个值类型相同,进行 === 比较。


2.如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:


a如果一个是null、一个是undefined,那么相等。

b.如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。

c.如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。

d.如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象。(这个目前我也不太懂)

e.任何其他组合,都不相等。

例如:


“1” == true

类型不等,true会先转换成数值 1,现在变成 “1” == 1,再把"1"转换成 1,比较 1 == 1, 结果为true。


三、三等于号的作用(注意===只在JavaScript中出现)


从前面我们已经知道

= 赋值运算符

== 等于


三、三等于号的作用(注意===只在JavaScript中出现)


从前面我们已经知道

= 赋值运算符

== 等于


因为a,b的类型不一样

===用来进行严格的比较判断


下面我们具体看看===的规则用来判断两个值是否相等:

1、如果类型不同,则不相等;

2、如果两个都是数值,并且是同一个值,那么相等; (有一个例外,如果其中至少一个是NaN,那么不相等) (判断一个值是否是NaN,只能用isNaN()来判断) ;

3、如果两个都是字符串,每个位置的字符都一样,那么相等;否则不相等;

4、如果两个值都是true,或者都是false,那么相等;

5、如果两个值都引用同一个对象或函数,那么相等;否则不相等;

6、如果两个值都是null,或者都是undefined,那么相等。


四、双等于号和equls的区别


1.==和equals的区别

  • 前面我们知道==可以用来比较基本类型和引用类型,判断内容和内存地址
  • equals用来判断两个对象内容是否相等

注:我们可以从equals源码发现


 Compares this string to the specified {@code StringBuffer}.  The result
     * is {@code true} if and only if this {@code String} represents the same
     * sequence of characters as the specified {@code StringBuffer}. This method
     * synchronizes on the {@code StringBuffer}.


即:equals只能针对string类型比较,比较的两者不是String类型,一定会返回false

2.在String之间的判断


    String str1 = "hello";//存在于常量池中,堆栈
    String str4 = "hello";
    String str2 = new String("hello");//存放在堆中
    String str3 = new String("hello");
    String str5 = str2;
    System.out.println(str1.equals(str2));//true
    System.out.println(str3.equals(str2));//true
    System.out.println(str1==str2);//false
    System.out.println(str3==str2);//false
    System.out.println(str1==str4);//true
    System.out.println(str5==str2);//true

字符串缓冲池是程序在运行的时候创建的一个字符串缓冲池。

当使用 String str4 = “hello”; 这样的表达是创建字符串的时候,

程序首先会在这个String缓冲池中寻找相同值的对象,

因为在String str1 = “hello”;中,str1先被放到了池中,所以在str4被创建的时候,程序找到了具有相同值的 str1,并将str4指向s1所引用的对象"hello"


3.Java面试宝典中是这样解释的


该条来自博客


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


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


equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:

    String a=new String("foo");
    String b=new String("foo");

两条new 语句创建了两个对象,然后用a,b 这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a 和b 中存储的数值是不相同的,所以,表达式a==b 将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。


在实际开发中, 我们经常要比较传递进行来的字符串内容是否等, 例如, String input= …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的。应该牢记,字符串的比较基本上都是使用equals 方法。


如果一个类没有自己定义equals 方法,那么它将继承Object 类的equals 方法,Object 类的equals方法的实现代码如下:


boolean equals(Object o){
    return this == o;
}

这说明,如果一个类没有自己定义equals 方法,它默认的equals 方法(从Object 类继承的)就是使用 == 操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals 和使用 ==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals 方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。


总结下来,对于等号又有了新的认识!真好

目录
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
14 2
|
7天前
|
人工智能 监控 数据可视化
Java智慧工地信息管理平台源码 智慧工地信息化解决方案SaaS源码 支持二次开发
智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三大体系为基础应用,实现全面高效的工程管理需求,满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效,为监管平台提供数据支撑。
24 3
|
12天前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
12天前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
42 3
|
14天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
18天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
21天前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。
|
22天前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
25天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
27天前
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
59 0