Java经典面试题——equals和==的区别
在正式讲解equals和==区别之前,让我们先来了解一下对象在JVM内存中的存在形式:
就拿这个Person对象来举例:
Person person=new Person();
person.name="彭于晏";
person.height=185;
class Person{String name;//名字int height;//身高
}
为了更好的理解对象在JVM内存中的存在形式
我先将这个Person对象在JVM中的内存分配图画出:
下面具体分析:
首先,当系统执行Person person=new Person();这串代码时会在栈中定义一个变量叫做person,由于Person对象时引用类型,因此他会指向我们调用Person类的无参构造器时在堆区开辟的地址,假设为0x0011,这个地址就用于保存我们的Person对象。
然后,由于我们在Person类中定义了两个属性name和height,因此堆区这个地址中有两个空间,一个用于存放name,一个用于存放height。height的数据类型是int,属于基本数据类型,所以他会把数据直接放在height的这个空间中。而name的数据类型是String类型,属于引用类型,因此,0x0011这个地址中存放的name实际上是一个地址,他的数据 "彭于晏" 是被放在了方法区一个叫常量池的地方,这个数据在常量池也会有一个地址,假设为0x0022,则name中存放的地址就是0x0022。
JVM内存分布介绍完毕,下面看实例
public class Equals {public static void main(String[] args) {Person p1=new Person();p1.name="李华";Person p2=new Person();p2.name="李华";System.out.println("p1==p2的结果为:"+(p1==p2));System.out.println("p1.name.equals(p2.name)结果为:"+p1.name.equals(p2.name));System.out.println("p1.equals(p2)结果为:"+p1.equals(p2));}
}
class Person{public String name;
}
运行结果如下:
p1==p2的结果为:false
p1.name.equals(p2.name)结果为:true
p1.equals(p2)结果为:false
先初步了解下==和equals的区别
==是一个比较运算符
(1) ==:既可以判断基本类型,又可以判断引用类型
(2) ==:如果判断基本类型,判断的是值是否相等
(3) ==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
equals是Object类中的方法
(4)equals:只能判断引用类型
(5)默认判断地址是否相等,子类中往往重写了该方法(后面结合源码分析),用于判断内容是否相等,比如Integer,String
对运行结果进行解析
1.第一个输出代码 System.out.println("p1==p2的结果为:"+(p1==p2));中,由于p1和p2都是new出来的对象,因此p1和p2都是指向了各自在堆内存中开辟的一个空间,因此p1和p2地址值不一样,输出为false;
2.第二个输出代码 System.out.println("p1.name.equals(p2.name)结果为:"+p1.name.equals(p2.name));中,使用的是equals方法,我们知道p1.name是一个字符串,而在字符串类型中,equals方法已经被重写,比较的是p1.name和p2.name的值,而p1.name和p2.name的值都是"李华",所以输出true;
3.第三个输出代码 System.out.println("p1.equals(p2)结果为:"+p1.equals(p2));中,p1是一个自定义类,没有重写equals方法,所以这里的equals方法仍然是来自其最高父类Object,比较的是两者的地址,由于p1和p2都是new出来的对象,因此p1和p2都是指向了各自在堆内存中开辟的一个空间,因此p1和p2地址值不一样,输出为false;
结合源码对equals进行分析
Object类中equals的JDK源码如下
public boolean equals(Object obj) {
return (this == obj);
}
很容易看出Object类中的equals方法判断的是否为同一对象
但是在Object的一些子类比如String类中,equals方法被重写,源码如下
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;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;
}
第一个if语句用于判断传入的对象是不是当前对象,如果是就直接返回true,
第二个if语句用于判断传入的对象是否是String类型,如果是,则先向下转型,将传入的对象强转成String类型,然后再用if语句判断两个字符串长度是否相同,如果相同,再用while循环一个一个的比较字符,只有所以字符都一样,才返回true,否则返回false。因此String类中将equals方法重写用于去判断值是否相等。
总结
equals除了只能判断引用类型外,其底层实现在没有被重写的情况下和==是一致的,都是判断地址是否相等,但在被子类重写的情况下,则是去判断引用类型的内容是否相等。
这里需要注意的是:共有两种方法可以创建引用类型
一种是直接赋值,这种情况下,会把值直接存入常量池,不会重新分配地址,因此这时候如果赋的值相同,则不管是用==比较还是用equals比较,返回的都是true。
另一种是用new的方式,每次new都会重新分配一个地址,所以这时候即使赋值相同,但是两者指向的地址却不同,所以用==比较仍然是会返回false,但由于引用类在继承Object类时对equals进行了改写,比较的是内容,因此在赋值相同情况下,返回true。
Java经典面试题——equals和==的区别相关推荐
- java面试题_阿里大厂流出的数百道 Java 经典面试题
BAT 常问的 Java基础39道常见面试题 1.八种基本数据类型的大小,以及他们的封装类 2.引用数据类型 3.Switch能否用string做参数 4.equals与==的区别 5.自动装箱,常量 ...
- Java经典面试题一
转载自 Java经典面试题一 题目一 面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1.抽象: 抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽 ...
- Java经典面试题答案解析(1-80题)
前言 前几天,在茫茫的互联网海洋中寻寻觅觅,把收藏的800道Java经典面试题都发出来,有小伙伴私聊我要答案.所以感觉没有答案的面试题是没有灵魂的,于是今天先整理基础篇的前80道答案出来哈~ 所有的J ...
- Java经典面试题汇总200道
超详细的Java学习资料汇总 Java经典面试题汇总 Java 基础 1. JDK 和 JRE 有什么区别? 2. == 和 equals 的区别是什么? 3. 两个对象的 hashCode()相同, ...
- Java经典面试题整理及答案详解(八)
简介: Java经典面试题第八节来啦!本节面试题包含了进程.线程.Object类.虚拟内存等相关内容,希望大家多多练习,早日拿下心仪offer- 了解更多: Java经典面试题整理及答案详解(一) J ...
- Java经典面试题整理及答案详解(五)
Java经典面试题第五弹来啦!本节面试题主要是针对Java初级基础提问,看看你还记得多少? 1.String str="hello",这个字符串对象在栈内存中明明有一个引用(str ...
- Java经典面试题整理及答案详解(三)
简介: 以下是某同学面试时,面试官问到的问题,关于面试题答案可以参考以下内容- 上一篇:Java经典面试题整理及答案详解(二) Java面试真题第三弹接住!相信通过前两节的学习,大家对于Java多少有 ...
- 拒绝面试造火箭,工作拧螺丝——Java经典面试题分享『带答案』
本文转载自:拒绝"面试造火箭,工作拧螺丝"--Java经典面试题分享『带答案』 1. Java三大版本 Java2平台包括标准版(J2SE).企业版(J2EE)和微缩版(J2ME) ...
- Java经典面试题 带答案(五)
Java经典面试题 带答案(五) Java 面试笔试题汇总 一.编程语言(Java)-2 二.软件工程方面-9 三.智力测试-9 四.数据库-12 五.Java框架方面 -14 六.XML方面-17 ...
最新文章
- 软件工程师的职业生涯
- c++ const 类型检查
- 20160626001 O2O Website
- Jquery Mobile 百度地图 Demo
- DataParallel 和 DistributedDataParallel 的区别和使用方法
- Java SE 基础:线程
- JavaScript高级教程——(19)构造函数、原型、原型链、继承
- 7种常用的数据标注工具
- 松本行弘的程序世界。
- existed hive ods_hive外部表
- 酷安uwp版|酷安uwp版客户端
- python中msg是什么意思_MSG是什么意思?
- Windows7 Ghost 旗舰装机版
- Anbox源码分析(三)——Anbox渲染原理(源码分析)
- Frida调用静态函数和非静态函数
- storm 2.2.1 java + idea实现wordcount
- Synopsys逻辑综合及DesignCompiler的使用
- python怎么打开图片_新手教学——python怎么打开图片
- 手动绘制R语言Logistic回归模型的外部验证校准曲线(Calibration curve)(2)
- 将文件传到免费服务器上,将文件传到服务器上
热门文章
- C++学习笔记(B站黑马程序员C++教程)
- linux 重定向偶尔失效,Linux crontab 输出重定向不生效问题解决
- 多摄像头多目标追踪指标(Multi-Target Multi-Camera Tracking, MTMC Tracking)
- python带cookies发送post请求_Python: 模拟post请求时的相关问题:cookie,json
- 苹果打开一个html文件一直闪,【报Bug】iphone6s 页面进场白色闪烁
- 怎样去除桌面图标下的底色[XP系统]
- Centos8.2安装配置 VNC 远程桌面Xfce、解决输入法VNC无法使用的问题、解决浏览器无法播放视频的问题
- CAD关于标注样式当前标志样式操作(com接口c#语言)
- 树莓派python安装库的位置
- 关于37%法则的探究