==和equals的深度分析
==的分析
1.对于基本数据类型,比较的是他们的具体内容是不是一样,跟他们的内存地址无关。举个栗子:
public class Test{ public static void main(String[] args) {
int i = 10;
double j = 10.0;
float m = 10.0f;
char k = 10;
boolean b = true; System.out.println(i == j);
System.out.println(i == m);
System.out.println(m == k);
System.out.println("*******************");
//System.out.println(i == b); 很明显,布尔型不能和其他基本数据类型比较,编译报错.
System.out.println(System.identityHashCode(i));
System.out.println(System.identityHashCode(j));
System.out.println(System.identityHashCode(m));
System.out.println(System.identityHashCode(k));
System.out.println(System.identityHashCode(b));
}
}
输出结果:
true
true
true
*******************
366712642
1829164700
2018699554
1311053135
118352462
分析:
①根据比较的结果和内存地址来看,内容一样,内存地址不一样,但是返回的结果都是true,说明比较的 时候只看变量中存储的内容是否相同,而跟内存地址无关。
②==比较的两边数据需要能强制转换成同一类型,比如
int和double的比较,会强制转换到double。 ③布尔类型不能和int,float,double,char等基本数据类型做比较,编译时就报错。
2.对于引用数据类型的比较:
public class Test{ public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
String name1 = "琼宝";
String name2 = "琼宝"; System.out.println(name1 == name2); // true
System.out.println(System.identityHashCode(name1)); //366712642
System.out.println(System.identityHashCode(name2)); //366712642 System.out.println(t1 == t2); //false
System.out.println(System.identityHashCode(t1)); //366712642
System.out.println(System.identityHashCode(t2)); //1829164700
System.out.println(System.identityHashCode(new Test())); //2018699554
System.out.println(System.identityHashCode(new Test())); //1311053135
System.out.println(new Test() == new Test());
}
}输出结果:
true
366712642
366712642
false
366712642
1829164700
2018699554
1311053135
false
分析:
①对于引用数据类型,此时涉及到两块内存的问题, 而且比较的也是内存地址是否相同,比如执行语句
Test t1 = new Test() Test t2 = new Test()时,会开辟两块内存,一块用于储存t1 t2,一 块用于储存两个 new Test()。而很明显的是,t1和t2的内存地址不一样,就连两个new Test()的地 址都不一样,所以此时用==来比较的时候,结果必然是false.(补充:t1和t2中存储的其实是new Test() 对象使用的内存的首地址。) ②对于String类型来说,内容相同的时候,其内存地址也相同,比较的时候看的也是地址。
②如果要比较对象中存储的内容是否相同(不是比较地址),那么==就无法实现,此时需要equals.
equals的分析
1.先看一个equals比较的栗子:
public class TestEquals {
public static void main(String[] args) { TestEquals t1 = new TestEquals();
TestEquals t2 = new TestEquals();
System.out.println(t1.equals(t2)); //false String s1 = new String();
String s2 = new String(); System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
System.out.println(System.identityHashCode(new String()));
System.out.println(System.identityHashCode(new String()));
System.out.println(s1.equals(s2)); // true
}
} 输出结果:
false
366712642
1829164700
2018699554
1311053135
true
2.分析:
①t1和t2的比较是false,而s1和s2的比较是true,这里就涉及到了equals方法的重写问题,先看 Object类 中equals的源码:
public boolean equals(Object obj) {
return (this == obj);
}
② 对于s1.equals(s2) ,
this就是s1,obj是s2,而源码中的比较用的是==,很明显是引用数据类型的比 较,看的是s1和s2的内存地址,上面的分析已经知道他们的地址不一样,所以结果自然就是false.
③而s1和s2的比较结果是true,这是因为在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;
}
④通过和object中equals源码的对比可以看出,String中的equals方法比较的不再是对象的地址,而是看 两个对象内容,或者两个对象的属性是否都一样。
⑤像String,Date,File…等类都对equals方法进行了重写。
总结
1.==用于比较基本数据类型时,比较的是内容是否相等,比较引用数据类型时,看的是内存地址是否相等。
2.equals只能比较引用数据类型(对象),没被重写之前,使用==来比较内存地址,重写后比较的是对象的具 体内容和属性是否一致。
3.创作不易。感谢支持,欢迎转载转发,但请注明出处。
4.如对你有帮助,老板大气,感谢打赏一杯熬夜咖啡。
5 .QQ 321662487


==和equals的深度分析的更多相关文章
- java集合框架(1) hashMap 简单使用以及深度分析(转)
java.util 类 HashMap<K,V>java.lang.Object java.util.AbstractMap<K,V> java.util.Hash ...
- const与readonly深度分析(.NET)
前言 很多.NET的初学者对const和readonly的使用很模糊,本文就const和readonly做一下深度分析,包括: 1. const数据类型的优势 2. const数据类型的劣势 3. r ...
- 转:[gevent源码分析] 深度分析gevent运行流程
[gevent源码分析] 深度分析gevent运行流程 http://blog.csdn.net/yueguanghaidao/article/details/24281751 一直对gevent运行 ...
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...
- AndroidService 深度分析(2)
AndroidService 深度分析(2) 上一篇文章我们Service的生命周期进行了測试及总结. 这篇文章我们介绍下绑定执行的Service的实现. 绑定执行的Service可能是仅为本应用提供 ...
- 深度分析如何在Hadoop中控制Map的数量
深度分析如何在Hadoop中控制Map的数量 guibin.beijing@gmail.com 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数 ...
- MapReduce深度分析(二)
MapReduce深度分析(二) 五.JobTracker分析 JobTracker是hadoop的重要的后台守护进程之一,主要的功能是管理任务调度.管理TaskTracker.监控作业执行.运行作业 ...
- MapReduce深度分析(一)
MapReduce深度分析(一) 一.数据流向分析 图为MapReduce数据流向示意图 步骤1.输入文件从HDFS流向到Mapper节点.在一般情况下,存储数据的节点就是Mapper运行的节点,不需 ...
- 【JVM】深度分析Java的ClassLoader机制(源码级别)
原文:深度分析Java的ClassLoader机制(源码级别) 为了更好的理解类的加载机制,我们来深入研究一下ClassLoader和他的loadClass()方法. 源码分析 public abst ...
随机推荐
- 后台开发小白必学服务器框架——UDPServer
毕业后加入了一家大型的互联网公司的音视频产品部门做后台开发,其实我本身是学习自动化的,研究生的方向嵌入式系统,对互联网可是一知半解,因此能进入这样一个大公司还是很幸运的. 刚开始工作的半年应该是在上份 ...
- java操作RabbitMQ添加队列、消费队列和三个交换机
假设已经在服务器上安装完RabbitMQ.我写的教程 一.发送消息到队列(生产者) 新建一个maven项目,在pom.xml文件加入以下依赖 <dependencies> <depe ...
- vue项目中安装使用vux
vux是个vue的移动端框架. 目前移动端UI框架这么多,为啥选择vux呢?vux虽然说是个个人维护项目,但是有15000+个star,应该不比其他的团队开源框架差. 最重要的是,目前要做微信公众号和 ...
- Vue 指令总结大全
1.v-text v-text主要用来更新textContent. <p>{{msg}}</p>与<p v-text="msg2"></p ...
- Towards Universal Object Detection by Domain Attention
论文及代码 论文地址:https://arxiv.org/abs/1904.04402 代码:http://www.svcl.ucsd.edu/projects/universal-detection ...
- jquery ajax提交数据给后端
大家好,今天铁柱兄给大家带一段jquery ajax提交数据给后端的教学. 初学javaweb的同学前端提交数据基本上都是用form表单提交,这玩意儿反正我是觉得不太好玩.而JavaScript aj ...
- LVM扩容之xfs文件系统
LVM的基础请见:https://www.cnblogs.com/wxxjianchi/p/9698089.html 一.放大LV的容量.放大容量是由内而外来操作的. 1.设置新的lvm分区:用fdi ...
- mysql中给查询出的结果集添加自增序号
select (@i:=@i+1) i,emp.* from emp,(select @i:=0) it 按部门分组并按薪资总和从大到小排序求薪资总和第二高的部门名称和薪资总和:select c.en ...
- linux+docker+nginx如何配置环境并配置域名访问
一.环境准备 1)下载php环境包,下载地址为:https://www.php.net/downloads.php 2)安装docker,这个主要的作用就是用来安装mysql.你也可以不需要安装这个东 ...
- CCNA 之 八 交换基础 VLAN TRUNK VTP
交换基础 主要知识点: 二层交换基础 Vlan的概念 Trunk的概念 VTP 二层交换基本配置 首先来看下园区网分层结构 交换机的主要功能: Address learning 学习MAC地址 会维护 ...