Pre
案例
String str2 = new StringBuilder("计算机").append("技术").toString(); System.out.println(str2 == str2.intern()); String s2 = new StringBuilder("计算机技术").toString(); System.out.println(s2 == s2.intern());
读者可以先自行推演一下答案 ,是不是所有的JDK版本都是一样的? 还是说不同的JDK版本的答案不尽相同 ?
答案
String str2 = new StringBuilder("计算机").append("技术").toString(); System.out.println(str2 == str2.intern()); //1.8 true 1.6 false String s2 = new StringBuilder("计算机技术").toString(); System.out.println(s2 == s2.intern()); //1.8 false 1.6 false
【1.6 】
【1.7 】
【1.8】
字符串常量池在不同JDK版本的位置变化
Jdk1.6及之前: JVM存在永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池
Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里
Jdk1.8及之后: 无永久代,变成了元空间,运行时常量池在元空间,字符串常量池里依然在堆里
String中的intern方法是一个 native 的方法
JDK1.7(含) + ,当调用 intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串, 否则,将intern返回的引用指向当前字符串 。
jdk1.6版本需要将 s1 复制到字符串常量池里
JDK1.7(含)+
JDK1.6
明白了哈
intern源码
intern 在JDK里是native ,所以只能找C++的代码了。
JDK8对应的哈
看看basic_add 返回的啥
oop : ordinary object pointer 指针
加入到常量池,这个常量池StringTable , 也是个hash结构 ,最后返回string(), 这其实是个指针引用。
so ~ , 这样就好理解intern机制了吧 。