Java 字符串常量池

news2024/9/20 20:45:31

目录

一、池化概念

二、字符串常量池

1. 概述

2. String对象的创建过程

1)直接使用字符串常量进行赋值

2)通过new创建String类对象

3)结论

4)intern方法


一、池化概念

先看如下的一段代码:

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

之所以会出现上述情况,是因为在Java程序中,类似于:1,2,3,3.14,"hello"等字面类型的常量经常频繁使用,为了使程序的运行速度更快,更节省内存,Java为8种基本数据类型和String类都提供了常量池。其中为String类提供的常量池叫做字符串常量池。

"池" 是编程中的一种常见的,重要的提升效率的方式,除了常量池,还有各种内存池,线程池,数据库连接池等。

为了节省存储空间以及程序的运行效率,Java中引入了:

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

二、字符串常量池

1. 概述

字符串常量池在 JVM 中是 StringTable 类(实际是一个固定大小的 HashTable )

不同 JDK 版本下字符串常量池的位置以及默认大小是不同的:

JDK 版本字符串常量池位置大小设置
Java 6(方法区)永久代固定大小:1009
Java 7堆中可设置,没有大小限制,默认大小:60013
Java 8堆中可设置,存在大小限制,最小:1009

2. String 对象的创建过程

不同 JDK 版本对于字符串常量池的处理方式不同,以下是 Java 8 中的情况:

1)直接使用字符串常量进行赋值
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true

上述在常量池中的情况大致如下:

StringTable 底层是一个哈希表,因此是通过数组+链表来组织数据的,数组上的每个元素是一个链表:

s1 创建时,常量池中没有 hello 对应的String对象,因此需要创建一个添加到常量池中(创建一个节点,插入到链表中)。

节点的 String 对象引用就指向了一个新的 String 对象,该对象的字符数组引用就指向了一个内容为 hello 的新的字符数组。然后将该 String 对象引用赋值给 s1。

s2 创建时,发现常量池已经有了 hello 对应的 String 对象,因此就直接将常量池的 String 对象引用赋值给 s2。

因此 s1 和 s2 是指向了同一个 String 对象的引用。

2)通过new创建String类对象

s3 创建时,堆中会创建一个全新的 String 对象,然后也会去常量池寻找是否存在字面值相同的String 对象,此时发现有(但是不会直接将常量池中的 String 对象的引用直接赋值给 s3 ),然后这个全新的 String 对象的 val 指向常量池中的 String 对象的 val 指向的字符数组,相当于这个全新的对象和常量池中的对象内部的 val 引用指向的是同一个字符数组。

如果没有,那么就还是会创建一个对应的 String 对象添加到常量池,大致过程和上述一致。并且添加到常量池的对象和上述创建的全新的对象,毫无关系,是两个不同的对象,只是它们的 val 引用指向的是同一个字符数组。

s4 同理。

因此 s3 和 s4 都是全新的 String 对象,和其他 String 对象不相同。

3)结论

无论如何,所有方式创建的字符串,常量池中都会保存一份。使用第一种方式创建 String 对象的效率更高,并且更节省空间。因为第一种方式没有创建出新的 String 对象,都是指向常量池中的 String 对象的引用。而第二种方式每次都是创建一个全新的 String 对象。

4)intern方法

intern 方法的作用就是手动将创建好的 String 对象引用添加到常量池当中

char[] ch = new char[]{'a', 'b', 'c'};
String s1 = new String(ch);
String s2 = "abc";
System.out.println(s1 == s2);  // false

char[] ch = new char[]{'a', 'b', 'c'};
String s1 = new String(ch);    // s1 对象的引用并不在常量池中
s1.intern();                   // 将 s1 对象的引用添加到常量池中
String s2 = "abc";             // ”abc“ 对象的引用已经存在于常量池当中,直接取引用进行赋值
System.out.println(s1 == s2);  // true

第一种情况示意图:

第二种情况的示意图:

注意:String类传入一个字符数组的构造方法,内部不是直接使用传入的字符数组,而是拷贝一个新的。

public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1967591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM实战系列(1)—强强联合Langchain-Vicuna应用实战

背景 本文主要介绍一下,基于Langchain与Vicuna-13B的外挂OceanBase知识库项目实战以及QA使用,项目地址: github.com/csunny/DB-G… 在开始之前,我们还是先看看效果~ 自Meta发布LLaMA大模型以来, 围绕LLaMA微调的模型…

为什么越来越多的IT青年转行网络安全?

目前,我国互联网已经从爆发增长期进入平稳发展阶段,同时每年大量计算机相关专业的毕业生涌入就业市场,导致IT行业逐渐趋于饱和状态,甚至出现裁员现象,去年很多大厂都有裁员,不少程序员再就业成了难题。 面…

大彩触摸屏与单片机通讯

目录: 一、概述 1、触摸屏简介 2、安装软件 1)设置VSPD软件 2)设置VisualTFT软件 3)设置串口软件 二、单片机发送指令给触摸屏 1、发送文本 2、显示与隐藏控件 1)通过指令助手生成指令 2)隐藏…

IDEA启动springBoot项目,显示构建和正在启动XxxApplication之后无反应

今天拉其他项目组的代码,然后发现IDEA启动不了项目,点击启动一闪而过,啥提示也没有,因为之前有过类似IDEA出错的经验,所以知道怎么排查。 首先打开IDEA日志输出,然后看具体是什么错 帮助>Tail Log in Co…

Linux用户无法访问Github怎么办?

进入Steam官网:Watt Toolkit 1.点击下载 2.在点击授权并下载 3.尽量选择Nas分流(德国) 4.然后选择最新版本 5.点击Linux版本它会自动文件夹 6.双击,他会自动下载 7.下载完成后进行解压,解压后进入目录 8.右键在此打开终端,在终端输入,运行此脚本 …

揭秘!焦虑症不只是心理战,这些躯体化症状你中招了吗?

引言 在这个快节奏、高压力的时代,焦虑症已成为许多人难以言说的秘密。它不仅悄无声息地侵蚀着我们的心理健康,还可能以一系列令人意想不到的躯体化症状显现,让人误以为自己只是“身体出了点小毛病”。今天,就让我们一起揭开焦虑…

[工具推荐]前端加解密之Burp插件Galaxy

如果觉得该文章有帮助的,麻烦师傅们可以搜索下微信公众号:良月安全。点个关注,感谢师傅们的支持。 免责声明 本号所发布的所有内容,包括但不限于信息、工具、项目以及文章,均旨在提供学习与研究之用。所有工具安全性…

肖扬率团队到北京军区干休所与离退休老干部座谈

在中国人民解放军建军97周年到来之际,为弘扬拥军优属光荣传统,营造尊崇关爱军人的浓厚氛围,世界中医药联合会骨伤科专业委员会副会长肖扬教授率团队遵从上级部门安排于7月31日上午到北京军区干休所看望离退休的老干部和多位老将军的后代&…

【DRF性能优化】

一、背景 项目中有一个查询脚本的接口,查询20条数据需要5min,性能很差,需要优化 二、问题排查 查看代码发现,serializers中,发现了一个奇怪的查询 查询脚本时,关联的脚本版本的一些字段也需要查询出来,…

安卓单机游戏:世界盒子手机游戏,最新版,春秋MOD整合 下载

《世界盒子》(WorldBox)是一款由Maxim Karpenko制作的沙盒模拟类游戏。这款游戏允许玩家在游戏中扮演上帝的角色,使用神力来创造和改变像素世界。玩家可以利用水、沙子、土壤、森林、人类、种子、动物等元素,以及温度、降雨等环境…

【数据结构】了解哈希表,解决哈希冲突,用Java模拟实现哈希桶

哈希表的概念 哈希表(Hash Table)是一种高效的数据结构,用于实现快速的数据存储和检索。它通过将数据映射到一个数组的索引位置,从而能够在平均情况下实现O(1)的时间复杂度进行查找、插入和删除操作。 哈希表的基本概念包括以下…

LLM应用-prompt提示:让大模型总结生成PPT

参考: https://mp.weixin.qq.com/s/frKOjf4hb6yec8LzSmvQ7A 思路:通过大模型生成markdown内容,通过markdown去生成PPT 技术:Marp(https://marp.app/)这里用的这个工具进行markdown转PPT 1、让大模型生成Ma…

川土微电子|高性能模拟芯片供应商

上海川土微电子有限公司,成立于2016年,总部位在上海,并于深圳、北京、杭州设有分支机构,产品涵盖隔离与接口、驱动与电源、高性能模拟三大产品线以及μMiC战略产品( micro-Module in Chip)。目前产品已广泛…

玩转大模型之五(测试FastGPT高级编排)

一、高级编排 FastGPT 从 V4 版本开始采用新的交互方式来构建 AI 应用。使用了 Flow 节点编排(工作流)的方式来实现复杂工作流,提高可玩性和扩展性。但同时也提高了上手的门槛,有一定开发背景的用户使用起来会比较容易。 编排方…

局域网内远程控制桌面软件推荐

在现代办公环境中,局域网(LAN)内的远程桌面连接已成为提升工作效率和促进团队协作的关键技术之一。无论是需要访问办公室内部服务器,还是在家工作时远程操作公司电脑,局域网内的远程桌面都能满足这一需求。本文将探讨在…

互联网家政小程序,为大众带来高效、便捷的服务

随着人口老龄化的严重和社会生活节奏的加快,大众对家政服务的需求日益增加,家政行业的市场规模逐渐扩大! 在科技的推动下,家政行业开始向数字化发展,“互联网家政”的模式推动了市场的快速发展。互联网家政小程序借助…

安卓Intent

文章目录 Intent新建一个活动显示Intent隐式Intent同多隐式Intent用法向下一个活动传递数据向上一个活动返回数据 Intent Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。…

EPM 和 EPM-P 系列功率计

EPM 和 EPM-P 系列功率计 是德(KEYSIGHT)简述 EPM 功率计提供了 CW 和平均功率测量功能。EPM-P 功率计提供了峰值、均值、峰值均值比和时间选通功率测量功能。 EPM系列 功率计表 功能特点 EPM 和 EPM-P 系列提供高性能、可编程的功率计,以执行连续波、平均功率和…

Wasm(WebAssembly) 编译环境搭建、浏览器调用

参考:https://www.deanhan.cn/wasm.html 以下以Windows系统 c 语音编译为wasm为例说明: 安装npm访问Node.js官方网站:https://nodejs.org/ 点击“Download”按钮,选择Windows版本(32位或64位)。 下载完成后,运行安装程序。 安装过程中,确保选中了“Add Node.js to …

42 字典创建与删除

字典(dict)是包含 “键:值” 元素的无序可变序列,字典中的每个元素包含用冒号分隔开的 “键” 和 “值” 两部分,表示一种映射或对应关系,也称为关联数组。定义字典时,每个元素的 “键” 和 “值” 之间用冒…