一、intern()方法

运行时常量池是方法区的一部分,在JDK 8的时候,方法区概念的落地实现由永久代变成了元空间

intern()方法的源代码如下图所示
在这里插入图片描述

  • intern()方法是一个本地方法
  • 调用该方法时,如果字符串常量池中已经存在一个等于此String对象的字符串,就直接从常量池中返回这个字符串对象的引用
  • 如果调用该方法的这个字符串对象,目前字符串常量池中还并不存在这个字符串对象,也就是说这个字符串对象是首次出现的,那么就新建并添加这个字符串对象到字符串常量池中,并返回新建的字符串对象的引用

二、字符串常量Java内部加载

public class intern {
    public static void main(String[] args) {
        String str1 = new StringBuilder("hello").append("world").toString();
        System.out.println(str1);
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());

        System.out.println();

        String str2 = new StringBuilder("ja").append("va").toString();
        System.out.println(str2);
        System.out.println(str2.intern());
        System.out.println(str2 == str2.intern());
    }
}

输出结果
在这里插入图片描述
StringBuilder创建的字符串对象是在上,调用intern()方法会把这个字符串对象实例引用放到字符串常量池,并返回这个字符串对象的引用。因此intern()返回的引用和由StringBuilder创建的那个字符串实例就是同一个对象

上述代码都是创建了一个字符串对象并调用intern()方法把这个字符串对象引用放到了字符串常量池中,但是“helloworld”字符串返回true,而“java”字符串却返回的是false,这说明“java”这个字符串之前已经创建过,并把引用存放在了字符串常量池中。

实际上这个“java”字符串,早就在系统进行初始化时,类加载器加载一些必需的类sun.misc.Version这个类的时候,这个“java”字符串就已经进入常量池。
在这里插入图片描述

所以很显然Version这个类创建的“java”字符串对象的引用和StringBuilder创建“java”字符串对象的引用并不是同一个

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐