关于Java String的intern()方法

2019-02-26 17:29发布

问题:

        String s1="abc",s2=new String("abc");
        s2.intern();
        System.out.println(s1==s2);

在 jdk10 的环境下,我知道s2的引用指向的是堆,我想问s1指向的哪个区域呢?常量区吗?如果是常量区,这个常量区是位于堆里的吗?
在这个上下文中,s2.intern();的作用是什么呢?是在常量区加入了指向s2的引用吗?

回答1:

很久前研究过这个问题,看深入理解jvm的时候有关于intern的讨论,当时是说intern方法在jdk6和jdk7之间会有不同。
常量池一般是类加载的时候确定了一些自定义的常量,比如s1="abc"。但是intern方法可以让方法在运行时也可以往常量池中添加常量。
intern方法大致理解为:
如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回。
一般在jdk6和jdk7以后会有区别,是因为常量池在7以后被拿到堆中了。



回答2:

这是个有意思的问题呀

        String s1 = "Test";
        String s2 = "Test";
        String s3 = new String("Test");
        final String s4 = s3.intern();
        assertTrue(s1 == s4);


回答3:

s1指向的是常量池,常量池是位于方法区的,区别于堆,你可以了解下jvm的内存,至于String的intern()方法返回的是规范化文本,简单说就是使用equals方法与常量池中的字符串比较,看看有没有相同的字符串,如果有直接返回常量池中的引用,如果没有,则在常量池添加一个跟自己一样的字符串并返回引用



标签: intern string