JVM的字符串常量池在不同版本放在不同的内存中。线程共享内存:方法区(永久代)、堆内存。
jdk1.6版本:字符串常量池是放在永久代中,在永久代和堆内存地址是完全分离的,不会直接引用。
jdk1.7+版本:字符串常量池是放在堆内存中。
这里以jdk7+为例:
String.intern()方法目的是为了让字符串重用,减少内存使用。作用:如果在字符串常量池存在则返回字符串常量池的字符串引用,如果字符串常量池中不存在,则将字符串放入字符串常量池中,并且返回自身的引用。
“A”表示的字符串会直接放入字符串常量池中,包括new String(“A”);
String s1=new String("A");
System.out.println(s1==s1.intern());
new String("A"):这里在字符串常量池上建立一个“A”字符串,在堆内存中也创建了一个对象和引用s1.
s1.intern(): 因为字符串常量中存在“A”,所以返回的是字符串常量池中“A”的引用,
所以这里的结果是为:false
String s1=new String(“A”)+new String("B");
System.out.println(s1==s1.intern());
new String("A")+new String("B"); 这里在字符串常量池中创建了“A”、“B”字符串,在堆内存中创建了“A”、“B”、“AB”对象和s1引用。
s1.intern():这里因为字符串常量池中没有“AB”,所以将“AB”放入字符串常量池中,并且返回的是自己的引用(s1).
所以结果是:true
String s2=“AB”;
String s1=new String(“A”)+new String("B");
System.out.println(s1==s1.intern());
String s2="AB";这里只是在字符串常量池中创建“AB”字符串对象。
new String("A")+new String("B"); 这里在字符串常量池中创建了“A”、“B”字符串,在堆内存中创建了“A”、“B”、“AB”对象和s1引用。
s1.intern():这里因为字符串常量池中有“AB”,所以返回的是字符串常量池中“AB”的引用。
所以结果是:false
在这里感谢大神:https://blog.youkuaiyun.com/seu_calvin/article/details/52291082
我只是看完自己总结了一下: