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.
输出为: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.
输出:false、false、true
分析:intern()方法就是返回字符串对象的规范化表示形式,也就是返回对应的缓冲池中的对象,这样也就不难理解了,s1.intern()和s2.intern()都指向缓冲池中的"abc",s1本来就指向缓冲池中的“abc”,s1指向堆内存中的创建的对象,所以结果一目了然,缓冲池中只有一个“abc”。
3.
输出:true、false
分析:hello、hel、lo都指向缓冲池中的"hello",输出中,"hel"+"lo"是指向缓冲池中的"hello",而"hel"+lo是在堆里面生成"hello"对象并返回的,所以不等。
说到这里大家应该都比较明白了,我也希望自己可以坚持下去,多看大牛们的博客,自己动手实践,把自己的理解写出来给大家,感谢阅读,喜欢的话点个赞吧~
字符串对象是一种特殊的对象,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"对象并返回的,所以不等。
说到这里大家应该都比较明白了,我也希望自己可以坚持下去,多看大牛们的博客,自己动手实践,把自己的理解写出来给大家,感谢阅读,喜欢的话点个赞吧~
相关文章推荐
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- 在Java中,用作字符串比较的运算符" == "和".equals()"的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- java学习:字符串比较“==”与“equals”的差异及与c#的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- Java中字符串比较时==和equals的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- Java中使用==和使用equals来比较两个字符串的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- 字符串的比较==与equals的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别