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()判断方法区已有该值不能在方法区新建,共用该值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从网上复制的,看别人的比较全面,自己搬过来,方便以后查找。原链接:https://www.cnblogs.com/...
    lxtyp阅读 5,150评论 0 9
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,862评论 3 83
  • 一、运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区、虚拟机栈、本地方法栈、堆、程序计数器,...
    加油小杜阅读 5,389评论 1 15
  • 其实身为画渣的我一年也摸不了几次笔,昨天看了有插画师的作品,看得我也心痒难耐,所以有了这几张图。 不过在手机上看我...
    刘阿biu阅读 3,165评论 2 2
  • 记得第一次吃黄焖鸡米饭是在合肥出差,当时很赶时间,还没来得及细细品尝,就开始赶路。但始终记得第一口的味道,一直念念...
    王小妞61阅读 4,264评论 2 17