String.intern()
intern说明
《深入理解Java虚拟机》
String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的 字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加 到常量池中,并且返回此String对象的引用。
实现逻辑:
"东西".intern();
这里的"东西"为堆中的new String(“aa”)对象引用
String str = new String(“aa”);
str.intern();
这里的"东西"为常量池中aa对象
“aa”.intern();
if (在常量池中存在内容与“东西”相同的(字符串内容相同)) {
返回该存在的引用;
}
else if (在常量池中不存在内容与“东西”相同的(字符串内容相同)) {
if (jdk7) { //常量池中可以放对象/引用
把"东西"放入常量池,如果是"东西"为对象就放入对象,如果是引用就放入引用;
返回在常量池中放入的对象/引用的引用;
}
if (jdk6) { //常量池中只放对象
if ("东西"为对象) {
把"东西"放入常量池;
}
else if ("东西"为引用) {
新建一个对象,该对象内容为引用指向的对象的内容;
把新建的对象放入常量池;
}
返回在常量池中放入的对象的引用;
}
}
jdk6和jdk7区别
此函数分为jdk6和jdk7两个版本区别
jdk6字符串常量池在方法区
jdk7字符串常量池在堆中
String str = new String("a") + new String("b");
str.intern();
-
执行String str = new String(“a”) + new String(“b”);结果为:
- 常量池:a,b
- 堆:new String(“a”) , new String(“b”),StringBuild对象,new String(“a”) + new String(“b”)(下面用new String(“ab”)说明)
jdk6内存结构为:
jdk7内存结构为:
执行str.intern();
查看常量池中是否存在与等于str的对象/引用,可以看到常量池只存在a,b没有内容为ab的对象,所以需要在常量池中放入一个内容为ab的一个”东西“。放入的”东西“就是区别所在:
jdk6在常量池放入的是一个ab对象
jdk7在常量池放入的是str这个引用即new String(“ab”)
jdk6执行后内存结构为:
jdk6执行后内存结构为:
String ab = new String("a") + new String("b");
ab.intern();
String ab2 = new String("ab");
String ab3 = new String("a") + new String("b");
String ab4 = "ab";
// jdk8
System.out.println(ab == ab2); // fasle
System.out.println(ab == ab3); // false
System.out.println(ab == ab4); // true