细谈Java的String类

news2024/11/17 11:56:39

目录

1. 创建对象的思考

2. 字符串常量池(StringTable)

3. intern方法


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)先看s1 和 s2 在内存是怎样的

(2)再看s3和s4在内存是怎样的

 (3)最后来看s1和s3

 

上述程序创建方式类似,为什么s1和s2引用的是同一个对象,而s3和s4不是呢?

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

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

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

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

2. 字符串常量池(StringTable)

字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(一种高效用来进行查找的数据结构,后序给大家详细介绍),不同JDK版本下字符串常量池的位置以及默认大小是不同的:

JDK版本字符串常量池位置大小设置
Java6 (方法区)永久代 固定大小:1009
Java7堆中 可设置,没有大小限制,默认大小:60013
Java8堆中 可设置,有范围限制,最小是1009

总结:

结论:只要是new的对象,都是唯一的。
通过上面例子可以看出:使用常量串创建String类型对象的效率更高,而且更节省空间。用户也可以将创建的字符串对象通过 intern 方式添加进字符串常量池中。 

3. intern方法

intern 是一个Native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中

    public static void main(String[] args) {
        char[] ch = new char[]{'a', 'b', 'c'};
        String s1 = new String(ch); // s1对象并不在常量池中
        s1.intern();
        // s1.intern();调用之后,会将s1对象的引用放入到常量池中
        String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
        System.out.println(s1 == s2);
    }

注意:

 

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

这种方式构造一个String对象,里面的vlaue数组是对ch的拷贝,而不是指向ch!!!

(1)没调用intern方法之前

 (2)调用了intern方法之后

 

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

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

相关文章

【数据结构 03】循环队列

一、原理 循环队列从功能角度具有队列的性质,即遵从先进先出原则,但是其存储方式是顺序存储。 循环队列的存储空间大小通常都是固定的,通过前指针和尾指针的移动控制循环队列数据的增删。 特征:顺序存储、先进先出、容量有限&a…

docker打包python镜像全教程

1.目录结构如下 2.使用dockfile安装: FROM python:3.7.7 ADD ./pdf_reader /code # 设置code文件夹是工作目录 WORKDIR /code # 安装支持 RUN pip install -r requirements.txt CMD ["python3", "Api.py"]dockfile最好在linux系统上创建&am…

网络原理-TCP_IP(2)

TCP协议 TCP全称为"传输控制协议(Transmission Control Protocol)".协议如其名,要对数据的传输进行一个详细的控制. TCP协议段格式 源/目的端口号:表示数据从哪个进程来,到哪个进程去. 32位序号/32位确认序号:后面详细讲. 4位TCP报头长度:表示该TCP头部有多少个32位…

恒创科技:云服务器公网带宽选择多少合适?有计算公式吗?

随着云计算技术的不断发展,越来越多的企业和个人选择使用云服务器来部署应用和存储数据。而在选择云服务器时,公网带宽是一个重要的参数,它直接影响到服务器的网络性能和数据传输速度。 公网带宽是指云服务器在互联网上的数据传输速率&#x…

Mongodb安装Linux

确定你的CentOS 版本 使用以下命令: /etc/centos-release下载Mongodb 解压tgz压缩包 创建data和log文件夹 , 确定你的文件夹访问权限 在log文件夹里面创建mongodb.log文件(这一步很重要 ! ! !) touch mongodb.log创建mongodb.conf文件 在你的mongodb文件夹下 vi mongo…

虚拟机扩容后黑屏卡死解决方法

亲测有效,首先一般是在扩容后黑屏的,现象为开机后看到个横线光标不闪,黑屏,进入不了桌面。原因是硬盘已经满了,所以解决方法就是清理硬盘。所以首先还是要解决登录问题。 开机时按 esc 键进入 GNU GRUB,选择…

浙大发布Agent学习框架,13B 模型达到 ChatGPT 水平!

2023 年下半年,AI Agent 正式开启「大模型下半场」。 自“人工智能”这门学科创立之初,一种可以“观察世界”-“思考推理”-“做出行动”-“反思学习”的人造代理就是构建通用人工智能的终极目标之一。而基于大模型的 AI Agent 借助大模型强大的推理判断…

github官网连接超时解决方案(图解版,亲测成功)

目录 一、521github镜像站1.1、521github镜像站访问地址 二、Github520镜像站2.1、Github520镜像站访问地址地址 三、UsbEAm Hosts Editor加速器3.1、UsbEAm加速器下载、安装及使用 四、SwitchHosts加速器4.1、SwitchHosts加速器下载、安装及使用 五、原名(Steam)目…

Android P 屏保和休眠相关知识

Android P添加屏保功能,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠 需求: 添加屏幕互保开关,默认关闭。只保留时钟,可设定指针和数字、夜间模式。启用时间改多长时间无操作进入…

LeetCode —— 137. 只出现一次的数字 II

😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️…

互联网加竞赛 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的人脸表情识别 该项目较…

angular 表单FormGroup笔记

一、校验 1、校验提示 <nz-form-item><nz-form-label>手机号码</nz-form-label><nz-form-control [nzErrorTip]"mobileTemplate"><input nz-input formControlName"mobile" placeholder"请输入" /><ng-templ…

springboot mybatis-plus 项目分层笔记

整体定义 config: 配置项&#xff0c;包含configuration注解 constants: 常量类enums: 枚举 exceptions: 全局异常处理&#xff0c;自定义异常&#xff0c;RestControllerAdvice 注解 fia3: 三大器依据执行顺序&#xff1a;过滤器filter、拦截器interceptor、切面aop 简称 fia…

Flutter canvas 画一条波浪线 进度条

之前用 Flutter Canvas 画过一个三角三角形&#xff0c;html 的 Canvas 也画过一次类似的&#xff0c; 今天用 Flutter Canvas 试了下 感觉差不多&#xff1a; html 版本 大致效果如下&#xff1a; 思路和 html 实现的类似&#xff1a; 也就是找出点的位置&#xff0c;使用二阶…

Python实现avif图片转jpg格式并识别图片中的文字

文章目录 一、图片识别文字1、导包2、代码实现3、运行效果 二、avif格式图片转jpg格式1、导包2、代码实现3、运行效果4、注意事项 三、Python实现avif图片转jpg格式并识别文字全部代码 在做数据分析的时候有些数据是从图片上去获取的&#xff0c;这就需要去识别图片上的文字。P…

Buffer缓冲区类设计实现

目录 类设计理念 类设计接口函数 类设计函数实现 测试 正常读取与写入 相同类型拷贝 扩容测试 按行读取 类设计理念 类设计接口函数 #include <vector> #include <cstdint>#define BUFFER_DEFAULT_SIZE 1024 // Buffer 默认起始大小 class Buffer { pr…

Redis -- String 字符串, 计数命令,字符串操作

"学如逆水行舟&#xff0c;不进则退。" 目录 Redis的String字符串 常见命令 set get mget mset setnx setex psetex 计数命令 incr incrby decr decrby incrbyfloat 字符串操作 append getrange setrange strlen 小结 string内部编码 Redis…

全方面解析msvcp110.dll文件的修复教程,六个修复msvcp110.dll文件丢失问题的详细方法

msvcp110.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2012 Redistributable Package&#xff08;微软视觉C 2012重新分配包&#xff09;的一部分。这个文件主要包含了C标准库中的一些函数&#xff0c;特别是与内存管理、异常处理、字符串处理和数学计算相关的…

部署YUM仓库服务

一、yum仓库 1. yum简介 yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红帽软件包管理器的缩写&#xff09;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以…

动态gif制作方法是什么?一个网站在线制作

一般我们说的gif动图就是动态图片是一种图片格式。Gif动图就是由一帧一帧的静态画面合成一张有动态效果的图片。接下来。给大家讲一讲gif生成&#xff08;https://www.gif.cn/&#xff09;的方法吧&#xff01;很简单不需要下载软件&#xff0c;手机、pc均可操作&#xff0c;只…