• 字符串常量池位于JVM哪里


    在这里插入图片描述

    Java6 和6之前,常量池是存放在方法区(永久代)中的。Java7,将常量池是存放到了堆中。Java8 之后,取消了整个永久代区域,取而代之的是元空间。运行时常量池和静态常量池存放在元空间中,而字符串常量池依然存放在堆中

    jdk1.6 以及之前下字符串常量池是在方法区中,是与堆完全独立的两个空间。intern()方法能使一个位于堆中的字符串在运行期间动态地加入到字符串常量池中(字符串常量池的内容是程序启动的时候就已经加载好了),如果字符串常量池中有该对象对应的字面量,则返回该字面量在字符串常量池中的引用,否则,创建复制一份该字面量到字符串常量池并返回它的引用

    jdk1.7,1.8 下字符串常量池已经转移到堆中了,是堆中的一部分内容,jvm 设计人员对 intern() 进行了一些修改,当执行 intern() 时,jvm 不再把字符串对应的字面量复制一份到字符串常量池中,而是在字符串常量池中存储一份字符串的引用,这个引用指向堆中的字面量,当运行到 String s = "hellohello"时,发现字符串常量池已经存在一个指向堆中该字面量的引用,则返回这个引用。

    实例1:

    1. 常量与常量的拼接结果在常量池中;
    2. 常量与常量拼接时,只要其中有一个是变量 ,结果就在堆中;
    public class Test{
    	public static void main(String[] args){
    		String str = "helloworld";
    		String str1 = "hello";
    		String str2 = "world";
    		
    		String str3 = "hello" + "world";
    		String str4 = "hello" + str2;
    		String str5 = str1 + "world";
    
    		System.out.println(str1 == str2); //false
    		System.out.println(str == str3); //true
    		System.out.println(str == str4); //false
    		System.out.println(str == str5); //false
    		System.out.println(str4 == str5); //false
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    实例2:

    String s = new String("abc"); //创建了几个对象
    // 2个
    // 第一个对象是"abc"字符串存储在常量池中;
    // 第二个对象是创建在Heap堆中的String对象;
    // 这里的s是放在栈里面的指向了Heap堆中的String对象。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    实例3:

    new 出来的 String 对象可以通过 intern() 方法将堆中的字符串对象放到常量池;这个方法的意思就是先到常量池中查询当前对象是否存在,存在就返回常量池中地址,不存在就加入常量池,也返回加入时常量池地址。

    // 双引号直接放入常量池
    String s1 ="1";
    String s2 = new String("1");
    System.out.println(s1 == s2); // false
    
    //先到常量池中查询是否有"1",存在就将常量池中对象返回,不存在就放到常量池中
    String s3 = new String("1").intern();
    System.out.println(s1 == s3) // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    String t3 = new String("2") + new String("2");
    String t4 = "22";
    System.out.println(t3 == t4); // false
    t3 = t3.intern();
    System.out.println(t3 == t4);  // true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    参考:https://blog.csdn.net/Tao_Yuanqiang/article/details/108040262

  • 相关阅读:
    C++:类的默认成员函数------构造函数&&析构函数(超详细解析,小白一看就懂!)
    亚马逊云科技:让生成式AI真正走向普惠
    移远EC600U-CN开发板 11.15
    视频号视频怎么保存到手机,视频号视频怎么保存到手机相册里,苹果手机电脑都可以用
    OpenAI宫斗大戏,奥特曼面临的选择
    lodash源码
    Spring学习(三):MVC
    机器学习笔记-02
    机器学习实验二:图像分类(Part five:可视化中间层激活结果 、Part six:可视化类别激活热力图 and Part seven:可视化卷积核)
    小公司里面的 Python 后端,数据库(MySQL)到底要学习到什么程度?
  • 原文地址:https://blog.csdn.net/qq_33732195/article/details/133417304