Android面试专题系列(一): String中"=="与equals的区别
不诗意的女程序媛不是好厨师~ 转载请注明出处,From李诗雨—blog.csdn.net/cjm24848365…
1.抛出问题
请说一下,String中"=="与equals()的区别,分析并预测如下代码的输出结果:
String str1 = "a" + "b" + "c";
String str2 = "abc";
String str3 = new String("abc");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str2 == str3);
System.out.println(str1.equals(str2));
System.out.println(str2.equals(str3));
System.out.println(str1.equals(str3));
System.out.println(str1.hashCode() + " " + str2.hashCode() + " " + str3.hashCode());
2.知其然知其所以然
2.1 String中的 == 比较
下面我们来从本质上,一个一个分析这三行代码:
String str1 = "a" + "b" + "c";
String str2 = "abc";
String str3 = new String("abc");

-
先看第一行代码
String str1 = "a" + "b"+ "c"
;当第一行代码被执行的时,String是存放在一个叫做常量池的地方。(而平时我们自己创建的普通对象 都是在堆内存里面的)。
此时,在常量池中实际上是产生了四个对象(字符串“a”,"b","c" 和链接完成之后的“abc”),str1是直接指向常量池中的"abc"对象的。
当此行代码执行完以后,在我们的堆内存中也会有一个空间,它的内容也是“abc"。并且这个空间会在堆内存中的 映射表里 注册一个”abc“对应的位置,它也就对应我们堆内存中的”abc“.
所以,当一行代码执行完以后,我们可以认为 在常量池和堆里面都有str1对应内容的副本。
-
再看第二行代码
String str2 = "abc";
第二行代码执行的时候,它首先要做的事情就是在常量池中去找,如果它能找到序列相同的(如“abc”),那它就直接定位在"abc"这个位置了。
所以,这个时候str1和str2,它们所存放的内存地址是相同的地方。
-
最后我们来看看第三行代码
String str3 = new String("abc");
当我们去执行第三行代码的时候,它需要在堆里面去new出一个空间“abc”。在new空间的过程中,str3会直接在映射表中注册,而不会在常量池中再去申请空间,它会直接定位到原来在堆内存中所开辟的空间(“abc”)。
通过上面的分析我们可以得出结论:
== 比较,比较的是内存的位置.
通过上图,我们可以看到,str1 和 str2 在内存中是同一个位置,而str3是在另一个不同的位置
所以,只有
str1==str2
.
即运行结果:
System.out.println(str1 == str2); //true
System.out.println(str1 == str3); //false
System.out.println(str2 == str3); //false
2.2 String中的equals比较
我们来看一下,String中equals的源码:

所以,String中equals的比较,比较的是字符串的内容。
则由上图我们可以知道 str1,str2,str3它们的字符串内容都相同(同是“abc”)。
即运行结果为:
System.out.println(str1.equals(str2)); //true
System.out.println(str2.equals(str3)); //true
System.out.println(str1.equals(str3)); //ture
2.3 关于hashCode
hashcode调用的都是堆内存中的方法。
所以,只要我们的数据 在堆内存中 是通用的 并且找的到,那么它们的hashcode值就相同。
即运行结果:

3.小结
在String中,
-
“==“比较的是内存中的位置。
-
equals()比较的是内容的字符序列(即内容)。
-
hashcode调用的都是堆内存中的方法,只要数据在堆内存中是通用的,hashcode值就相同。
积累点滴,做好自己~
转载自:https://juejin.cn/post/6844904103609384973