您的位置:首页 > 编程语言 > Java开发

Sting比较的“==”和“equals”的区别(字符串缓冲池)

2018-01-23 00:23 836 查看
本文涉及内存空间主要为:栈(存放引用变量等)、堆(存放new的对象)、字符串缓冲池(字符串特有的对象存放空间)

字符串对象是一种特殊的对象,String 类是一个不可变的类,也就说,String 对象一旦创建就不允许修改。String
类有一个对应的 String 池,也就是 String pool,每一个内容相同的字符串对象都对应于一个
pool 里的对象。也就是说String s1="abc", String s2="abc",共同指向pool中的“abc”,是相同的对象。

字符串缓冲池:不论String s3="abc",还是String s4=new String("abc"),都会先去字符串缓冲池中查看是否有“abc”,若有则不再重复创建,若没有则在字符串缓冲池中新建"abc",则s3指向缓冲池中的"abc"对象,s4指向堆中创建的对象。

注意:“==”永远都是判断内存地址是否相等,用于基本数据类型的比较。“equals”用于判断堆中内容是否相同。

那么我们来看下面的例子(以下实验结果都是在jdk1.8的环境下输出的):

1.

String s = "abc";
String s1 = new String("abc");
String s2 = new String("abc");
String s3 = "abc";

System.out.println(s == s1);
System.out.println(s.equals(s1));
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s==s3);
System.out.println(s.equals(s3));

输出为:false、true、false、true、true、true(这里为了格式没有回车)
分析:创建s:在字符串缓冲池中查找是否有"abc",找不到则自动创建"abc",并且s指向缓冲池中的"abc"。创建s1:查找缓冲池中是否已有"abc",有则不再创建,s1指向堆中新创建的对象。创建s2:查找缓冲池中是否存在,存在不再创建,s2指向堆中新创建的对象,注意这里的对象和s1指向的堆中的对象不是同一个。创建s3:查找缓冲池中是否已经有"abc",有则不再创建,s3指向缓冲池中的"abc"。

所以就比较明显了,四个对象中,s和s3指向缓冲池中的同一个对象,s1和s2指向堆内存中的不同对象。所以“==”判断内存地址结果一目了然,equals用于判断对象中内容,所以都为true。

2.

String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s == s1.intern());
System.out.println(s == s2.intern());
System.out.println(s1 == s2.intern());

输出:false、false、true

分析:intern()方法就是返回字符串对象的规范化表示形式,也就是返回对应的缓冲池中的对象,这样也就不难理解了,s1.intern()和s2.intern()都指向缓冲池中的"abc",s1本来就指向缓冲池中的“abc”,s1指向堆内存中的创建的对象,所以结果一目了然,缓冲池中只有一个“abc”。

3.

String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo");
System.out.println(hello == "hel" + lo);

输出:true、false
分析:hello、hel、lo都指向缓冲池中的"hello",输出中,"hel"+"lo"是指向缓冲池中的"hello",而"hel"+lo是在堆里面生成"hello"对象并返回的,所以不等。

说到这里大家应该都比较明白了,我也希望自己可以坚持下去,多看大牛们的博客,自己动手实践,把自己的理解写出来给大家,感谢阅读,喜欢的话点个赞吧~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息