JAVASE进阶:String常量池内存原理分析、字符串输入源码分析

news2024/11/23 15:15:10

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:JAVASE进阶:内存原理剖析(1)——数组、方法、对象、this关键字的内存原理
📚订阅专栏:JAVASE进阶
希望文章对你们有所帮助

String类型的变量是我们非常常用的,它是属于java.lang包下的,属于java核心包下的,直接可以使用。
这一部分的内容也是会出一点面经的,所以我需要重新梳理一下。
同时给了一个可能比较少见的问题,也就是用户输入的字符串,其底层是怎么执行的?这部分内容我会跟踪源码来做解析。

引入

先看下面语句:

String name = "哈哈哈";
name = "哈哈";

这里虽然只用了一次String语句进行声明,但是实际上还是创建了2个字符串,都创建在了字符串常量池中。因此第一句只是将字符串常量池中的"哈哈哈"的地址赋值给了左边的name,第二句是将常量池中的"哈哈"的地址赋值给了左边的name。这其中,并不存在"哈哈哈"字符串变为"哈哈"字符串的说法,即——字符串一旦创建成功,无法进行修改

字符串常量池

实际上,上述的创建方式一直都是最常用的创建方式,而且也是最推荐的方式,在这里进行一下比较。

创建String对象的两种方式:
1、直接赋值

String name = “哈哈哈”;

2、new关键字

构造方法说明
public String()创建空白字符串
public String(String s)根据传入的字符串创建字符串对象(很少用)
public String(char[] chs)根据字符数组,创建字符串对象
public String(byte[] chs)根据字节数组,创建字符串对象

字符串常量池(串池,StringTable)在之前一直都是在方法区(元空间)中的,而在jdk7开始,从方法区挪到了堆内存,但是底层的实现方式还是不变的。

查看下面语句:

String s1 = "abc";
String s2 = "abc";

第一条语句先从常量池中查看是否有这条字符串,没有就创建一个,并把地址赋值给s1,第二条语句在常量池中查找到这条字符串,直接返回地址给s2(复用),也就是说s1和s2指向了常量池中的同一条字符串了。

再看下面语句:

char[] chs = {'a', 'b', 'c'};
String s1 = new String(chs);
String s2 = new String(chs);

因为有new关键字,所以创建的过程全部在堆内存(不包括常量池)进行的,这时候会创建出两条字符串,并且s1和s2的地址是不一样的,即不会复用,显然更耗费空间。

所以,字符串常量池不仅代码简单,还因为复用机制更省内存。

字符串比较底层机理

分别分析下面语句的运行结果:

String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);

true

String s1 = "aaa";
String s2 = "bbb";
System.out.println(s1 == s2);

false

String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1 == s2);

false

在第三个例子中,值一样的字符串,比较结果却是false,所以需要搞明白==到底比较的是啥。

实际上,如果是基本数据类型,直接比较的就是真实值,而字符串由于涉及到了常量池和堆内存,显然是引用数据类型,而引用数据类型比较的是地址值,由于new出来的是在堆空间的,直接赋值的方式是在字符串常量池的,因此它们根本不可能是同一个地址,因此返回false。

因此,==的方式并不适合用来比较字符串,实际比较最好使用字符串比较函数:

boolean equals()
boolean equalsIgnoreCase(): 忽略大小写比较,比如验证码

字符串输入源码分析

真实场景下,字符串可能不是直接赋值的,而是要用户自己去输入的,那么用户自己输入的字符串到底是放在常量池中的还是放在堆内存中的呢?可以验证并跟踪源码分析。

查看下列语句:

Scanner sc = new Scanner(System.in);
String s1 = sc.next();
String s2 = "abc";
System.out.println(s1 == s2);

用户输入abc,但最终输出的是false,可以猜想到,用户输入字符串后,其创建是在堆空间中进行的,进行源码分析:

1、Ctrl+鼠标进入next方法查看一下,其返回的内容是一个token,token的来源是getCompleteTokenInBuffer方法:
在这里插入图片描述
2、跟踪getCompleteTokenInBuffer方法,可以看到源码非常长:
在这里插入图片描述
但是其实只要看关键的信息,也就是return的真实信息,那些return null的其实肯定不是我们重点关注的,因此定位到正确位置:
在这里插入图片描述
3、ctrl+左键跟踪进入group:
在这里插入图片描述
4、继续跟踪group(0):
在这里插入图片描述
5、再跟踪:
在这里插入图片描述
6、继续跟踪,发现没有返回值了,就是一个定义好的接口:
在这里插入图片描述
这其实就是java设计模式的原则了,用父类去替代子类,说明这个接口的实现类还是很多的,因此没办法从这里进行分析,回到上一层的subSequence。

7、右键点击subSequence方法,并点击go to,选择Implementation,即可找到其中的所有实现类:
在这里插入图片描述
8、显然我们需要寻找有关于String的,所以点击String进入:
在这里插入图片描述
在这里插入图片描述
9、跟踪进入:
在这里插入图片描述
其实看到这个return里面带着的new的字样大致就能猜到它底层肯定是用到了new关键字了。

10、跟踪newString方法跟踪,看到了底层的new关键字:
在这里插入图片描述
这就说明了,用户用键盘输入的字符串,即sc.next(),其底层是会用到new关键字,也就是说其创建在堆空间中,所以例子中的程序返回false。

跟踪源码心得

我不是第一次跟踪源码了,每次跟踪源码都会有一些不一样的心得,在这里讲一下我目前拥有的经验:

1、无所谓跟踪进去的方法有多么复杂,先查找return真实值的那部分,其是由哪个函数创建出来的,就跟踪那个函数
2、如果return真实值的情况有多种,可以快速筛查我们到底应该跟踪哪一个:
(1)看其中的英文注释
(2)看返回值和你的需求对不对得上
(3)看函数名称,自己翻译了猜一下
3、如果跟踪到没办法再跟踪的接口,说明是父类替代的子类,返回并右键查找正确的实现类(根据需求)

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

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

相关文章

嵌入式人工智能/深度学习/神经网络导论

加我微信hezkz17进入嵌入式人工智能技术研究开发交流答疑群 1 嵌入式人工智能,嵌入式深度学习含义?  嵌入式人工智能(Embedded Artificial Intelligence)是指将人工智能技术应用于嵌入式系统中,使其具备…

计算机网络_1.4 计算机网络的定义和分类

1.4 计算机网络的定义和分类 一、计算机网络的定义(无唯一定义)二、计算机网络的分类(从不同角度分类)1、交换方式2、使用者3、传输介质4、覆盖范围5、拓扑结构 笔记来源: B站 《深入浅出计算机网络》课程 一、计算机…

11张宝藏GIS开发思维导图,重点清晰,建议带走!

在GIS开发过程中,涉及大量的数据、地图、工具和技术。通过思维导图,我们可以将这些复杂的元素进行可视化,更好地理解和整理思路,提高开发效率。 同时思维导图利用了色彩、线条、关键词、图像等元素,可以加强记忆的可能…

Android平台如何实现RTSP转GB28181

为什么要做GB28181设备接入侧? 实际上,在做Android平台GB28181设备接入模块的时候,我们已经有了非常好的技术积累,比如RTMP推送、轻量级RTSP服务、一对一互动模块、业内几乎最好的RTMP|RTSP低延迟播放器。 Android平台GB28181接…

好书推荐丨保姆级Midjourney教程,这本写给大家看的设计书闭眼入!

文章目录 写在前面好书推荐Part.1Part.2Part.3 粉丝福利写在后面 写在前面 在AI绘画界,有每日经典一问:“你今天用Midjourney画了啥?”晒作品成为重头戏。 小红书上关于Midjourney出的图片点赞数惊人。 reddit上的恶搞幽默图片热度居高不下…

C#,幸运数字(Lucky Number)的算法与源代码

Lucky Number不是蔡依林的歌曲名字哦。 给你的NV朋友选一个幸运数字吧。 1 幸运数字是怎么产生的? 幸运数是整数的子集。与其进行大量理论研究,不如让我们来看看得出幸运数字的过程, 以整数集为例: 1,2,3,4,5,6,7,8,9,10,11,…

NAT 机制的工作流

NAT机制(网络地址映射)先把IP地址分成两个大类 1. 私网IP / 局域网IP 2. 公网IP / 广域网IP 要求公网的设备,对应的公网IP,都必须是唯一的,但是私网上/局域网上的设备,使用私网IP,只要保证局域网…

Linux 网络配置及基础服务

目录 一. 查看网络配置信息的相关命令 1.1 ifconfig 命令 作用 1: 作用 2: 拓展: 1.2 ip/ethtool命令 1.3 hostname命令 1.4 route 命令 1.5 netstat 命令 1.6 ss(socket statistics)命令 1.7 ping 命令 …

vscode 插件 Tailwind CSS IntelliSense 解决 class 提示问题

问题描述&#xff1a; 如下写js字符串是没有class智能提示的&#xff1a; const clsName bg-[#123456] text-[#654321] return <div className{clsName}></div>解决方案&#xff1a; 安装 clsx 依赖 pnpm i clsx设置 vscode 的 settings.json {"tailwin…

【C++】开源:Windows图形库EasyX配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Windows图形库EasyX配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#…

RabbitMQ 死信队列应用

1. 概念 死信队列&#xff08;Dead Letter Queue&#xff09;是在消息队列系统中的一种特殊队列&#xff0c;用于存储无法被消费的消息。消息可能会因为多种原因变成“死信”&#xff0c;例如消息过期、消息被拒绝、消息队列长度超过限制等。当消息变成“死信”时&#xff0c;…

对付勒索病毒,复杂的往往无法落地

一道道复杂门墙防护安全&#xff0c; 还是一个精密的锁更安全&#xff1f; &#x1f447;&#x1f447;&#x1f447; 在网络数据安全问题频发的当下&#xff0c;除了常规的备份、灾备措施以外&#xff0c;企业是否有做好应对最坏情况的准备&#xff1f;一旦病毒绕过了一道道…

极限的运算法则【高数笔记】

【定理】 1. 无穷小量 * 有界 无穷小量 简单理解为&#xff1a;0 乘以任何数都等于 0 &#xff0c;因为常数 0 是无穷小量 2. 设 lim f&#xff08;x&#xff09; a , lim g (x) b 加减&#xff1a;lim[f(x) g(x) ] lim f(x) g(x) a b 乘&#xff1a;lim[f(x)…

[Visual Studio] vs 2022中如何创建空白的解决方案

在Visual Studio 2022中创建一个空白的解决方案非常简单。请按照以下步骤操作&#xff1a; 打开Visual Studio。 在启动页面上&#xff0c;选择“创建新的项目”。 在“创建新项目”的对话框中&#xff0c;搜索“空白”。 在中间搜索结果中&#xff0c;选择“空白解决方案”…

同时添加多个的远程桌面工具,Windows远程桌面设置多用户同时登录

Windows Server 版本上的 Windows 远程桌面服务 (RDS) 允许多个用户同时登录。 但是&#xff0c;在标准的Windows桌面版本&#xff08;例如Windows 10&#xff09;上&#xff0c;默认情况下&#xff0c;远程桌面是为单个用户一次登录而设计的。 这被称为“管理远程桌面”模式。…

蓝桥杯2024/1/31----第十届省赛题笔记

题目要求&#xff1a; 1、 基本要求 1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台&#xff0c;完成本试题的程序设计 与调试。 1.2 选手在程序设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”。 1.3 请注意&#xff1a; 程序编写、调试完成后选手…

vmware读取坏掉的虚拟磁盘vmdk文件

vmware centos 7系统挂了&#xff0c;开不了机&#xff0c;重新安装ubuntu22系统&#xff0c;挂载centos7的vmdk文件。 1.找到坏掉的系统的vmdk文件 2.新系统添加硬盘 选择刚才旧系统的vmdk文件&#xff1a; 完成以后&#xff0c;看到多了一块硬盘&#xff1a; 3.读取新硬盘 &…

计算机毕业设计 | springboot 多功能商城 购物网站(附源码)

1&#xff0c; 概述 国家大力推进信息化建设的大背景下&#xff0c;城市网络基础设施和信息化应用水平得到了极大的提高和提高。特别是在经济发达的沿海地区&#xff0c;商业和服务业也比较发达&#xff0c;公众接受新事物的能力和消费水平也比较高。开展商贸流通产业的信息化…

SpringMVC-基本概念

一、引子 我们在上篇文章Spring集成Web中抛出了一个问题&#xff1a;为什么我们一直在自用Java Web阶段使用的Servlet来承接客户端浏览器的请求呢&#xff0c;我们熟知甚至是已经在日常开发中经常使用的Controller又与之有什么关系呢&#xff1f;我们将在本篇文章解答读者的这…

GitHub的使用操作

记得看目录哦&#xff01; 1. 创建仓库2. 下载desktop3. 把创建的库克隆到本地4. 文件拷贝到本地仓库![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7171ac6c4ca14e3b8d22717121f79c9e.png)5. 在网址后面加/compare进行比较6. 给系统添加功能 1. 创建仓库 2. 下载…