String中的intern

注:intern在jdk1.7之后与之前版本有所改动,区别不大文章后面会提。
先介绍下jvm内存模型:主要是本地方法栈,虚拟机栈,堆,方法区,程序计数器(版本不同时可能方法区没了,记不清1.8以后是不是取消了方法区,非本文重点以后修正)。

  • intern涉及到的主要是堆(存实例对象)方法区(存常量数据)
    代码中用String对象调用intern时,往往是在方法区中生成一个与堆中字符串对应的字符串常量,今后使用同一个常量时减少对堆中对象的访问,防止该对象的引用在以后指向其他String对象,导致获取不一致的String值。
    对一个String变量str1而言,使用已有变量str的intern赋值与直接使用"XXX"赋值会由于顺序的不一致导致不同的结果。

不写了,发现怎么都不如别人总结的好。下面这个博主写得很好了,学习:
https://blog.csdn.net/soonfly/article/details/70147205
主要是弄清楚intern的使用顺序,判断常量池中是否已经存在String对象的值。
弄清楚 -> 编译阶段:做final String的变量拼接时,不需要等到运行期,直接编译期就拼接完成。做String常量拼接也如是。final能够保证代码在初始化阶段安全性,这是jvm的规定,不会受到指令重排的影响。
弄清楚 -> 若对同一个常量值进行多次intern,其实都会指向同一处方法区的位置
弄清楚 -> 1.7之后,intern使用在直接常量赋值前时,方法区存放的堆中String对象的地址,以后无论多少个新的String对象使用intern,其返回值都是指向最初的那个String对象的堆地址,代码举例说明:

public class internTest {
    public static void main(String[] args) {
        String str2 = new String("str")+new String("01");
        str2.intern();
        String str3 = new String("str") + new String("01");
        String tmp = str3.intern();
        System.out.println(str2==tmp); 
    }
}

结果输入:true
结论:str2和tmp指向同一个位置的堆中对象。
分析:这是因为str2.intern时,已经在方法区生成了"str01"的存储位置(保存指向str2的堆地址),str3.intern()判断方法区已有该值不能在方法区新建,共用该值。

你可能感兴趣的:(String中的intern)