"==" equals和hashCode的联系和区别
写这篇文章的目的是自己彻底把三者搞清楚,也希望对你有所帮助。
1."=="运算符对与基本类型(int long float double boolean byte char short),比较的是他们的值。但是对于复合数据类型,比较的是他们的内存地址。
public class TestString {
public static void main(String[] args){
String s1="Hello";
String s2="Hello";
if(s1==s2){
System.out.println("s1==s2");
}else{
System.out.println("s1!=s2");
}
} }
运行结果 s1==s2
public class TestString {
public static void main(String[] args){
String s1=new String("Hello");
String s2=new String("Hello");
if(s1==s2){
System.out.println("s1==s2");
}else{
System.out.println("s1!=s2");
}
} }
运行结果 s1!=s2
分析:
当我们用String s1="Hello",再创建String s2="Hello"的时候,他会先去字符串缓冲池寻找相同的对象,因为我们之前创建了s1,s1被放在了字符串缓冲池中,
所以s2创建的时候,就找到了相同的值s1,s1和s2指向同一个对象。
当我们使用new的时候,就会新开辟一个内存地址,无论你怎么比较都不会相等的。
public class TestString {
public static void main(String[] args){
String s1="Hello";
String s2=new String("Hello");
if(s1==s2){
System.out.println("s1==s2");
}else{
System.out.println("s1!=s2");
}
} }
所以这个比较结果返回的也是s1!=s2,因为当我们用String s1="Hello"的时候,这个时候字符串缓冲池存在值Hello,但是接下来String s2=newString("Hello");他会怎么办呢,他会先去字符串缓冲池去找,如果池子没有Hello,他会在字符串缓冲池创建一个字符串常量“Hello”,如果存在就不在字符串缓冲池中创建。然后会在堆中创建一个新的对象(无论字符串缓冲池有没有都会执行)。所以说两者内存地址不相等。
2.equals是Object基类中的一个方法,java中所有的类都是继承Object 这个基类的。这个方法初始也是比较两者的内存地址的,这是原始的Object中的equals方法源码
public boolean equals(Object obj) {
return (this == obj);
}
很明显的看到方法里面的==,说明比较的是内存地址。
但是有一些类中有自身的equals方法把原本的方法覆盖掉了,就不再是比较两者的内存地址了,而是比较的内容值,例如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;
}
解释:如果是对象类型直接比较内存地址,如果是String类型逐一比较内容值。
public class TestString {
public static void main(String[] args){
String s1="Hello";
String s2=new String("Hello");
if(s1.equals(s2)){
System.out.println("s1==s2");
}else{
System.out.println("s1!=s2");
}
} }
结果返回:s1==s2。
注意:那这样的代码又会返回什么结果呢?
public class TestString {
public static void main(String[] args){
String s1="Hello";
String s2=new String("Hello");
s2=s2.intern();
if(s1==s2){
System.out.println("s1==s2");
}else{
System.out.println("s1!=s2");
}
} }
返回结果:s1==s2。为什么??答案:String#intern方法,这个方法是一个 native 的方法,“如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回”。
3.hashCode方法也是从Object类中继承过来的,它是用来鉴定两个对象是否相等,Object类中的的hashCode返回的是对象在内存中地址转换成的一串int数值,如果没有重写hashCode方法,任何对象的hashCode都不会相等的。恰恰String的hashcode重写了,你说气人不。如果两个对象equals相等,则hashCode必须相等,反之不成立。一般来说你重写了equals,也要重写HasCode。
"==" equals和hashCode的联系和区别的更多相关文章
- ==、equals()、hashcode()的关系和区别
==.equals().hashcode()概念 ==:它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不试同一个对象. equals():它的作用也是判断两个对象是否相等.但它一般有两种使 ...
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例 原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...
- equals()和hashCode()区别?
equals()和hashCode()区别? ------------------------------------------------- equals():反映的是对象或变量具体的值,即两个对 ...
- ==、equals、hashCode区别?
[==.equals().hashCode()区别?] 1)== 运算符用来比较两个变量的值是否相等. 即该运算符用于比较变量对应得内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是 ...
- Java == ,equals 和 hashcode 的区别和联系(阿里面试)
今天阿里的人问我 equals 与hashcode的区别,我答不上来, 仔细查了一下,做了总结: (1) == 这是Java 比较内存地址,就是内存中的对象: java中的==是比较两个对象在JVM中 ...
- 深入理解equals和hashCode关系和区别
为什么要说equals和hashCode这两个东西,一来是因为有不少小伙伴面试时被问过这个东西,二来则是因为如果了解了这两个东西的原理,那么实际的开发过程中,对效率和容错率上还是能帮上很大的忙! 直入 ...
- equals与hashCode的区别
equals与hashCode的区别 1.类中的equals方法是一定要重写/覆盖(Override)的,因为要让它按照设计的需求来根据特征值判断等价性. 这里的特征值,就是String类型的name ...
- 【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例 部分代码参考http ...
- java ==、equals、hashcode有什么区别
1.== 用来比较两个对象的存储空间 2.equals是Object类提供的方法之一,每个java类都继承Object类,所以每一个对象都具有equals方法,所以在没有覆盖equals方法的情况下, ...
随机推荐
- http缓存详解,http缓存推荐方案
前言 通过本文,你将了解到http缓存机制是怎样的,no-cache到底有没有缓存,地址栏回车,F5,ctrl+F5的区别,以及当下较为推荐的缓存方案等. 自从和前端组的同事一起整了个前端扫盲计划,想 ...
- Docker环境下搭建DNS LVS(keepAlived) OpenResty服务器简易集群
现在上网已经成为每个人必备的技能,打开浏览器,输入网址,回车,简单的几步就能浏览到漂亮的网页,那从请求发出到返回漂亮的页面是怎么做到的呢,我将从公司中一般的分层架构角度考虑搭建一个简易集群来实现.目标 ...
- Trace & Error log in file
1. Log机制 做一些大型项目的时候,对代码的调试最有效的办法往往是最直接.最简单的log机制: 即对可以出设置打印店,对应打印信息进行调试(当然是有gdb也许你会觉得很高大上,但是实际项目中,gd ...
- git remote: HTTP Basic: Access denied 错误解决办法
问题描述: git push 报 HTTP Basic: Access denied 错误 原因:本地git配置的用户名.密码与gitlabs上注册的用户名.密码不一致. 解决方案: 1. 如果账号密 ...
- .3-浅析express源码之applicaiton模块(2)-app.render
这个模块还漏了一个稍微复杂点的API,就是app.render,首先看官网的定义: app.render(view, [locals], callback) view为对应的文件名,locals为一个 ...
- C#中HttpWebRequest的用法详解
原文链接:http://www.cnblogs.com/love201314/p/5029312.html 1.HttpWebRequest和HttpWebResponse类是用于发送和接收HTTP数 ...
- Tomcat9.0环境搭建与源码编译
使用IntelliJ IDEA 搭建Tomcat9.0项目 准备条件: 下载源码 这里我们下载的Tomcat的源码版本是9.0.12. 下载地址: https://tomcat.apache ...
- Java下载execl表格
Java用POI往execl表格中写数据,并下载下来有两种方式 1.用poil的API创建表格,并设计好表格格式,然后往里面写数据 /** * execl导出 创建表格式,并写入数据 * @param ...
- CentOS命令行与shell操作(linux系管与运维二)
原创作品,转载请注明出处:https://www.cnblogs.com/sunshine5683/p/10293729.html 在上篇文章中总结了Linux常用的开机与关机以及重启的命令,今天继续 ...
- 素数回文(hdu1431)
素数回文 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...