package design.wlb.studyjava.demo.restudy.c4jvm专题.chapter02.c34StringTable面试题;
/**
* 有了前面的StringTable的基础,我们再来看这个面试题
*/
public class Client {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "a"+"b";
String s4 = s1 + s2;
String s5 = "ab";
String s6 = s4.intern();
//问
System.out.println(s3 == s4); //false
System.out.println(s3 == s5); //true
System.out.println(s3 == s6); //true
String x2 = new String("c") + new String("d");
String x1 = "cd";
x2.intern();
//问,如果调换了最后两行位置呢,如果是jdk1.6呢 【调换位置后x1 == x2的值,jdk1.8为true,jdk1.6为false】
System.out.println(x1 == x2);// false
}
}
我们有了前面的StringTable的基础,我们再来看这个面试题
s3 == s4 , 答案是false ,为什么呢?
s3是javac编译器优化直接变成了常量,jvm将其放入了串池,而s4是变量,jvm使用的是StringBuilder进行字符串的拼接,最后返回的是return new String(value,0,count);值是放在了堆中,故而堆中的对象与串池的对象比较,故而为false.
s3 == s5 , 答案是true ,为什么呢?
s3是串池对象,s5也是从串池中取的对象,故而相同。
s3 == s6 , 答案是true ,为什么呢?
s3是串池对象,s6是由s4调用intern方法返回的,s6是直接从串池中返回的串池对象,故而相同。
x1 == x2,答案为false,为什么呢?
x2是在堆中,x1在常量池中,后续x2调用intern方法,但串池中已经有了“cd”对象,该操作已被忽略,没有放入串池中,故而为false.
如果调换位置后
String x2 = new String("c") + new String("d"); x2.intern(); String x1 = "cd"; System.out.println(x1 == x2);调换位置后,x1 == x2 ,在jdk1.8中,值为true.为什么?
最先串池中没有"cd"对象,x2虽然是在堆中,但调用了intern方法,它将自身放入了串池。而x1是从串池里面取的值,故而两者相同。
调换位置后,x1 == x2 ,在jdk1.6中,值为false.为什么?
最新串池中虽然没有"cd"对象,x2虽然是在堆中,但调用了intern方法时,它是将它的复制品对象放入了串池中,自身没有进入串池,而x1是从串池里面取得值,两者一个属于堆中对象,另一个在串池中,故而为false。
好,这一篇就讲到这里。