• 再谈String


    一、字符串常量池

    1.1 创建对象的思考

    下面创建String对象的方式相同吗?

    public static void main(String[] args) {
       String s1 = "hello";
       String s2 = "hello";
       String s3 = new String("hello");
       String s4 = new String("hello");
       System.out.println(s1 == s2); // true
       System.out.println(s1 == s3); // false
       System.out.println(s3 == s4); // false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    上述创建方式类似,为什么s1和s2引用的是同一个对象,而s3和s4不是呢?
    Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池
    “池” 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 “内存池”, “线程池”, “数据库连接池”……
    为了节省存储空间以及程序的运行效率,Java中引入:

    1. Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
    2. 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份
    3. 字符串常量池

    1.2 字符串常量池(StringTable)

    字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(一种高效用来进行查找的数据结构),不同JDK版本下字符串常量池的位置以及默认大小不同:
    在这里插入图片描述

    1.3 再谈String 对象创建

    双引号引起来的就是字符串,都会放在常量中,创建字符串时,先去常量池中查找是否有当前这个字符串,常量池没有当前字符串就创建,有就不再创建

    1. 直接使用字符串常量进行赋值
    public static void main(String[] args) {
       String s1 = "hello";
       String s2 = "hello";
       System.out.println(s1 == s2); // true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    2. 通过new创建String对象

    public static void main(String[] args) {
       String s1 = "hello";
       String s2 = "hello";
       String s3 = new String("hello");
       System.out.println(s1 == s2); // true
       System.out.println(s1 == s3); // false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    结论:只要是new的对象,都是唯一的
    使用常量串创建String类型对象的效率更高,而且更节省空间。用户也可以将创建的字符串对象通过 intern 方式添加进字符串常量池中。
    3. intern方法
    将调用该方法的对象所指对象入池,如果常量池中存在,就不入池

    public static void main(String[] args) {
       char[] ch = new char[]{'h', 'e', 'l','l','o'};
       String s1 = new String(ch); // s1对象不在常量池中
       //s1.intern(); 调用之后,会将s1对象的引用放入到常量池中
       String s2 = "hello"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
       System.out.println(s1 == s2);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    intern调用前
    在这里插入图片描述
    intern调用后
    在这里插入图片描述

  • 相关阅读:
    【编译原理】Chapter1概述
    后厂村路灯:【干货分享】AppleDevelop苹果开发者到期重置
    某次 ctf Mobile 0x01 解题过程
    多监控系统产生的告警如何高效管理 - 运维事件中心
    面试突击37:线程安全问题的解决方案有哪些?
    Nwafu-OJ-1507 Problem 阶段2考试题目4 手机按键
    【小白使用-已验证】PhpStudy下载安装使用教程23.10.17
    PHP——爬虫DOM解析
    【JVM基础篇】类加载器分类介绍
    CV计算机视觉每日开源代码Paper with code速览-2023.10.19
  • 原文地址:https://blog.csdn.net/qq_64668629/article/details/133962079