再谈String

1、字符串常量池

1.1 创建对象的思考

下面是两种创建字符串对象的代码

public static void main1(String[] args) {String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2);//trueString s3 = new String("hello");String s4 = new String("hello");System.out.println(s1 == s3);//falseSystem.out.println(s3 == s4);//false}

上述程序创建方式类似,但为什么打印结果s1 == s2的时候是true,s1 == s3打印的时候是false,s3 == s4打印的时候是false呢?

在Java中,对于1、2、3、3.14、“hello”等字面类型的常量经常频繁使用,为了使程序运行更快,更节省内存,Java为8种基本类型和String类都提供了常量池。

"池" 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 "内存池", "线程池", "数 据库连接池" .... 比如:家里给大家打生活费的方式 1. 家里经济拮据,每月定时打生活费,有时可能会晚,最差情况下可能需要向家里张口要,速度慢 2. 家里有矿,一次性打一年的生活费放到银行卡中,自己随用随取,速度非常快 方式2,就是池化技术的一种示例,钱放在卡上,随用随取,效率非常高。常见的池化技术比如:数据库连接 池、线程池等。

为了节省程序存储的空间并且提高程序的运行效率,Java种引入了:

1、Class文件常量池:每个Java源文件编译后生成.class文件中会保存当前类中的字面常量以及符号信息。

2、运行时常量池:在.class文件被加载时候,.class文件中的常量池被加载到内存中称之为运行时常量池,运行时常量池每个类都有一份。

3、字符常量池:其具体概念会在讲解JVM时候详细解释。

1.2 字符串常量池

字符串常量池在Java的官方文档中并未详细说明,只是有一个在JVM中的StringTable类,实际上,是一个固定大小是HashTable(一种高效用来进行查找的数据结构),不同JDK版本下字符串常量池的位置以及默认大小是不同的:

1.3 字符串常量池的创建

如下代码,创建字符串就会先在字符串常量池先进行创建:

public static void main(String[] args){String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2);//true
}

那么创建过程是什么呢?下面通过画图进行讲解:

JVM中存在栈和堆。

当执行代码String s1 = "hello"的时候,堆中有一个StringTable类,其中是一个HashTable,在HashTable中存储的是一些链表的地址。当我们String s1 = "hello"的时候,常量池中会有一个空间来指向一个链表,这个链表会再指向一个String对象,这个String对象的value会指向一个字符数组,从而存储起来hello。 

同时,栈中开辟一块空间存放0x11。 这就是一次将常量放入常量池的过程。

存储字符串常量的时候,会先检查当前的常量池中 是否存在所要存储的常量,如果有的话,就不会再放入常量池中!

我们刚刚定义了String s2 = "hello",则先会再常量池中,寻找一下,是否有“hello”的常量,检查发现有,则直接再在栈中开辟一块空间给s2,但因为s2所要存储的常量以及在常量池中了,所以s2的地址直接指向常量池中是String对象即可。

所以在打印s1==s2的时候是true。

但如果是s3的创建方式:new String("hello")。 创建结果如图所示:

 即只要有new一个对象的发生,就一定会在堆中创建一个对象,则s4指向的地址为0x999的对象的地址,虽然也可以找到地址为0x88的hello,但s1和s3所存的地址就不一样了,所以在打印的时候,会出现s1 == s3的结果为false。

通过上面的例子可以看出:使用常量串创建String类型对象的效率更高,而且更节省空间。

1.4 intern方法

有如下代码:

    public static void main(String[] args) {char[] ch = {'a','b','c'};String s1 = new String(ch);String s2 = "abc";System.out.println(s2 == s1);}

通过上面内容的学习:我们知道输出的结果一定是false。

过程如下:

char[] ch = new char[]{'a', 'b', 'c'};之后,会在堆里有一个字符数组0x87,然后ch中存储地址0x87。

然后String s1 = new String(ch); 和上面一样,new出了新是对象String。

执行String s2 = "abc"的时候,过程如下,将 a b c放入常量池中 。

此时s1 和 s2指向的地址并不相同,索引打印结果自然是false。

但如果在String s1 = new String(ch)的代码之后,添加一行代码:s1.intern(),就可以实现将s1对象的引用放入到常量池。

    public static void main(String[] args) {char[] ch = {'a','b','c'};String s1 = new String(ch);String s2 = "abc";s1.intern();//1、先检查s1所指向的对象是否在常量池2、有则不入池,没有则入池System.out.println(s2 == s1);}

如果加上了这行代码,过程就会如下图所示,结果返回true: intern方法:

1.会先检查调用该方法所指的对象是否在常量池中存在。

2.如果有则不入池。

3.如果没有则入池。

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

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

相关文章

《深入浅出ProtoBuf:从环境搭建到高效数据序列化》​

ProtoBuf详解 1、初识ProtoBuf2、安装ProtoBuf2.1、ProtoBuf在Windows下的安装2.2、ProtoBuf在Linux下的安装 3、快速上手——通讯录V1.03.1、步骤1:创建.proto文件3.2、步骤2:编译contacts.proto文件,生成C文件3.3、步骤3:序列化…

基于PHP+Uniapp的互联网医院源码:电子处方功能落地方案

随着“互联网医疗”政策红利持续释放,互联网医院已成为推动医疗数字化转型的重要方向。在这一趋势下,电子处方功能模块作为核心环节,不仅直接关系到线上问诊闭环的实现,也成为系统开发中技术难度较高、业务逻辑最为复杂的一部分。…

ARM Cortex-M (STM32)如何调试HardFault

目录 步骤 1: 实现一个有效的 HardFault 处理程序 步骤 2: 复现 HardFault 并使用调试器分析 步骤 3: 解读故障信息 步骤 4: 定位并修复源代码 HardFault 是 ARM Cortex-M 处理器中的一种异常。当处理器遇到无法处理的错误,或者配置为处理特定类型错误&#xff…

基于归纳共形预测的大型视觉-语言模型中预测集的**数据驱动校准**

摘要 本研究通过分离共形预测(SCP)框架,解决了大型视觉语言模型(LVLMs)在视觉问答(VQA)任务中幻觉缓解的关键挑战。虽然LVLMs在多模态推理方面表现出色,但它们的输出常常表现出具有…

LangChain4j 搭配 Kotlin:以协程、流式交互赋能语言模型开发

Kotlin 支持 | LangChain4j Kotlin 是一种面向 JVM(及其他平台)的静态类型语言,能够实现简洁优雅的代码,并与 Java 库无缝互操作。 LangChain4j 利用 Kotlin 扩展和类型安全构建器来增强 Java API,为其增添特定于 Ko…

正大模型视角下的市场结构判断逻辑

正大模型视角下的市场结构判断逻辑 在多数交易策略中,结构识别往往先于方向判断。以正大的数据研判风格为例,其核心逻辑是:价格行为不能孤立解读,必须结合时间与成交效率来判断当前结构的有效性。 例如,一个上涨过程&…

Django 入门实战:从环境搭建到构建你的第一个 Web 应用

Django 入门实战:从环境搭建到构建你的第一个 Web 应用 恭喜你选择 Django 作为你学习 Python Web 开发的起点!Django 是一个强大、成熟且功能齐全的框架,非常适合构建中大型的 Web 应用程序。本篇将通过一个简单的例子,带你走完…

Unity 打包后 无阴影 阴影不显示

在项目设置里面->质量 这里面显示的是打包之后的质量 PS:注意运行质量 点击左键选择运行质量,这俩不一致就会导致,运行有阴影但是打包出来的平台没有阴影,原因就在这. 质量等级选择好之后 往下滑,在这里打开阴影,如果距离过远不显示阴影,就增加阴影距离.

python——面向对象编程

一、编程思想 面向过程编程(典型:c语言):是一种以过程为中心的编程思想。它强调流程化、线性化、步骤化的思考方式,实现思路就是函数。 面向对象编程:强调整体性和差异性。它将任何事物看做一个统一整个&…

宿主机和容器 ping 不通域名解决方法

目录 一、问题描述 二、宿主机解决方法 三、容器解决办法 一、问题描述 宿主机是Ubuntu,在宿主机上 ping 不通域名:xxxx.cn,但是个人电脑能 ping 通。 同时宿主机上的启动的k8s容器也无法ping通。 二、宿主机解决方法 ①编辑文件&#xff…

windows作业job介绍

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、作业job是什么?二、使用步骤1.代码示例 总结 前言 提示:这里可以添加本文要记录的大概内容: winapi网站: h…

ESG跨境电商如何为国内的跨境电商企业打开国外的市场

现在不管是国内还是国外,做电商的企业都非常的多,那么既然有这么多大电商公司,就要有为这些电商公司提供服务的公司,这就是ESG,它是专门为跨境电商服务的公司,那么这家公司的主要业务是什么呢?它…

龙虎榜——20250425

指数依然在震荡,等待方向选择,整体量能不搞但个股红多绿少。 2025年4月25日龙虎榜行业方向分析 一、核心主线方向 绿色电力(政策驱动业绩弹性) • 代表标的:华银电力(绿电运营)、西昌电力&…

大数据学习(112)-HIVE中的窗口函数

🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…

【MySQL】MySQL索引与事务

目录 前言 1. 索引 (index) 1.1 概念 1.2 作用 1.3 使用场景 1.4 索引的相关操作 查看索引 创建索引 删除索引 2. 索引背后的数据结构 2.1 B树 2.2 B+树的特点 2.3 B+树的优势 3. 事务 3.1 为什么使用事务 3.2 事…

python21-循环小作业

课程:B站大学 记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 循环语句小作业 for-in作业斐波那契 for 固定数值计算素数字符统计数字序列range 函数 水仙花…

深度学习小记(包括pytorch 还有一些神经网络架构)

这个是用来增加深度学习的知识面或者就是记录一些常用的命令,会不断的更新 import torchvision.transforms as transforms toPIL transforms.ToPILImage()#可以把tensor转换为Image类型的 imgtoPIL(img) #利用save就可以保存下来 img.save("/opt/data/private/stable_si…

Neo4j 可观测性最佳实践

Neo4j 介绍 Neo4j 是一款领先的图数据库管理系统,采用图数据模型来表示和存储数据。它以节点、关系和属性的形式组织数据,节点代表实体,关系表示节点间的连接,属性则为节点和关系附加信息。Neo4j 使用 Cypher 查询语言&#xff0…

算法训练营第三十天 | 动态规划 (三)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、01背包问题理论基础(一)动态规划五部曲确定dp数组以及下标的含义确定递推公式初始化dp数组确定遍历顺序 二、01背包问题理论基础&#…

玩机搞机基本常识-------小米OLED屏幕机型怎么设置为永不休眠_手机不息屏_保持亮屏功能 拒绝“烧屏” ?

前面在帮一位粉丝解决小米OLED机型在设置----锁屏下没有永不休眠的问题。在这里,大家要明白为什么有些小米机型有这个设置有的没有的原因。区分OLED 屏幕和 LCD屏幕的不同。从根本上拒绝烧屏问题。 OLED 屏幕的一些优缺点💝💝💝 …