浅析 String

浅析String

  • 一、创建字符串
  • 二、字符串与常量池
  • 三、字符串的不可变性
  • 四、字符串的拼接
  • 五、StringBuilder和StringBuffer

一、创建字符串

    //三种常用的构造字符串的方式public static void main(String[] args) {String str1 = "hello";String str2 = new String("world");char[] chars = {'a','b','c'};String str3 = new String(chars);}

注意: String是引用类型,内部并不存储字符串本身。通过查看String类的实现源码可以发现,字符串实际由两部分value数组、hash值组成,字符串实际保存在char类型的数组中:

二、字符串与常量池

📝以下程序输出的结果是什么?在此过程中创建了几个String对象?

    public static void main(String[] args) {String str1 = "Hello";String str2 = "Hello";String str3 = new String("Hello");System.out.println(str1==str2);System.out.println(str1==str3);}

分析: 双引号引起来的内容时存放在字符串常量池的,在直接赋值时,如果在字符串常量池中存在就直接返回常量池中字符串的引用,如果不存在则先在字符串常量池中创建一份。如果通过new创建字符串对象,同样会按照如上步骤检查常量池,只不过最后返回的是通过new创建的字符串对象。

最后我们说结论:此过程中str1会在常量池创建1个字符串对象,str2创建0个字符串对象,str3在堆区创建1字符串个对象。且str1==str2str1!=str3.

具体过程如下草图:

总结:

直接赋值产生10个字符串对象,使用newString()赋值时产生21字符串对象。赋值时先看字符串常量池,如果字符串常量池中没有,就在常量池中创建一个,如果有,前者直接赋值则直接引用,后者使用new String()在堆内存中还需创建一个实例对象(此时引用变量指向的是堆内存中创建的实例对象,而不是常量池中的实例对象)。

字符串常量池的作用:

“池” 是编程中的一种常见的, 重要的提升效率的方式。 对于字符串常量池来说,每次使用相同字面类型的常量时,Java会首先在字符串常量池中查找是否存在该常量的实例,如果存在则直接返回引用,避免重复创建新的实例,从而提高程序的运行速度并节省内存

三、字符串的不可变性

1.String类在设计时就是不可改变的,String类实现描述中已经说明了。

2.所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。

为什么 String 要设计成不可变的?

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

四、字符串的拼接

上面我们说String被设计成不可变类型,那么字符串的拼接该怎么解释呢?

    public static void main(String[] args) {String str="hello";str+="world";System.out.println(str);}

我们将上面的代码进行编译,其实它的底层实现如下:

    public static void main4(String[] args) {//上述代码的底层实现:String str = "hello";StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(str);stringBuilder.append("abc");str = stringBuilder.toString();System.out.println(str);}

所以,每次字符串的拼接底层都会创建一个StringBuilder对象,最后通过toString再返回一个新的String对象,可以想象如果在一个循环中使用字符串的拼接,那么它的效率将会非常低。话说回来,上面提到了StringBuilder,他究竟是什么?下面我们详细介绍:

五、StringBuilder和StringBuffer

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilderStringBuffer类。与String类的不同就是,在这些类中的对字符串修改的方法都是直接对原字符串进行修改,最后返回的都是修改后的原字符串。

此外,StringBuffer和StringBulider方法都是一样的,区别是StringBuffer被synchronized(锁)修饰,(线程安全)用在多线程情况下。单线程下一般用StringBuilder,因为频繁的加锁和释放锁也是需要耗费系统资源的。

(1)String、StringBuffer、StringBuilder的区别

  1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改。
  2. StringBuffer与StringBuilder大部分功能是相似的。
  3. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

(2)三者之间的转换

  1. StringBuffer或StringBuilder转String:调用toString方法
  2. String转StringBuffer或StringBuilder:利用它们的构造方法或append()方法

经典例题: 在不考虑常量池之前是否存在的情况下,以下总共创建了多少个String对象?

String str = new String("ab"); // 会创建多少个对象
String str = new String("a") + new String("b"); // 会创建多少个对象
//答案:2 5

解析:

对于代码 String str = new String(“ab”); 会创建两个String对象。首先,"ab"字面量会在字符串常量池中创建一个String对象,然后通过调用new String()构造函数创建第二个String对象。

对于代码 String str = new String(“a”) + new String(“b”); 会创建五个String对象。首先,字面量 “a” 和 “b” 分别会在字符串常量池中创建两个String对象。接着,通过 new String() 构造函数创建了另外两个String对象。最后,通过字符串拼接操作符 + 进行连接时,会创建一个新的String对象,其值为拼接结果 “ab”。

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

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

相关文章

恢复swp文件

swp文件_.swp文件_luminous_you的博客-CSDN博客 三、恢复源文件 正常URL:xxx/m.php 则尝试URL:xxx/.m.php.swp下载.swp文件代码 假设你的swp文件叫’.m.php.swp’ 可用带-r参数编辑#vi -r m.php 然后wq保存即可

图论 <最短路问题>模板

图论 <最短路问题> 有向图 1.邻接矩阵&#xff0c;稠密图 2.邻接表 &#xff08;常用&#xff09;单链表&#xff0c;每一个点都有一个单链表 &#xff0c;插入一般在头的地方插&#xff0c; 图的邻接表的存储方式 树的深度优先遍历 特殊的深度优先搜索&#xff0c…

Python检查端口是否打开(七种方法)

sock.connect_ex 使用socket模块的connect_ex来判断端口是否打开&#xff0c;如果返回值是0表示连接成功&#xff0c;端口打开&#xff0c;否则端口关闭。 import socketdef check_port(ip, port): sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeo…

Python导出SqlServerl数据字典为excel

sql代码 SELECTtableName D.name ,tableIntroduce isnull(F.value, ),sort A.colorder,fieldName A.name,catogary B.name,bytes A.Length,lengths COLUMNPROPERTY(A.id, A.name, PRECISION),scales isnull(COLUMNPROPERTY(A.id, A.name, Scale), 0),isOrNotNull Cas…

springboot 对接 minio 分布式文件系统

1. minio介绍 Minio 是一个基于Go语言的对象存储服务。它实现了大部分亚马逊S3云存储服务接口&#xff0c;可以看做是是S3的开源版本&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象…

Mac OS键盘常用快捷键

图形按键⌘Command 键⌃Control 键⌥Option 键⇧Shift 键⇪Caps Lockfn功能键 常用快捷键剪切、拷贝和粘贴 您可以在大多数 app 中使用这些快捷键来剪切、拷贝或粘贴选中的项目。其中包括文本、图片、音乐等等。您甚至可以在 Finder 中拷贝和粘贴文件&#xff0c;来将文件拷贝到…

Qt能跨多少个平台?Qt能支持多少个平台?

2023年8月5日&#xff0c;周日下午 目录 Qt所支持的平台更多关于Qt支持的信息 Qt所支持的平台 图中显示的平台都支持。 想要更详细的平台支持信息可以查看&#xff1a;Supported Platforms | Qt 5.15 更多关于Qt支持的信息 Qt - 支持的平台及语言

MongoDB 入门

1.1 数据库管理系统 在了解MongoDB之前需要先了解先数据库管理系统 1.1.1 什么是数据&#xff1f; 数据&#xff08;英语&#xff1a;data&#xff09;&#xff0c;是指未经过处理的原始记录。 一般而言&#xff0c;数据缺乏组织及分类&#xff0c;无法明确的表达事物代表的意…

Spring xml 方式整合mybatis 第三方框架

Spring整合MyBatis MyBatis提供了mybatis-spring.jar专门用于两大框架的整合。 ①&#xff1a;第一步&#xff1a; 导入MyBatis整合Spring的相关坐标&#xff1b; <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency><groupI…

一步一步介绍如何使用 OpenCV 创建虚拟笔和橡皮擦--附源码

文末提供相关源码下载 如果您只需在空中挥动笔即可虚拟地绘制一些东西,并且它实际上会将其绘制在屏幕上,那不是很酷吗?如果我们不使用任何特殊的硬件来实际实现这一点,可能会更有趣,只需简单的计算机视觉就可以,事实上,我们甚至不需要使用机器学习或深度学习来实…

代码随想录算法训练营第40天 343. 整数拆分 96.不同的二叉搜索树

343. 整数拆分 class Solution {public int integerBreak(int n) {if(n 2|| n 3) return n-1;if(n 4) return 4;int product 1;while( n > 4){product * 3;n-3;}return product *n;} }

服务器中了malox勒索病毒后怎么办怎么解决,malox勒索病毒解密数据恢复

服务器遭受Malox勒索病毒攻击后&#xff0c;快速解密并恢复数据至关重要&#xff0c;以便减少更大的经济损失。近期&#xff0c;新的一波malox勒索病毒正在肆虐&#xff0c;我们收到很多企业的求助&#xff0c;企业的服务器数据库遭到了malox勒索病毒攻击&#xff0c;导致系统内…

Spring框架中的Bean的生命周期

Spring Bean 的生命周期总体分为四个阶段&#xff1a;实例化 》属性注入》初始化》销毁 实例化&#xff1a; &#xff08;1&#xff09;实例化bean&#xff1a;根据配置文件中Bean的定义&#xff0c;利用java Reflection 反射技术创建Bean的实例&#xff01; 属性注入&#…

如何使用win10专业版系统自带远程桌面公司内网电脑,从而实现居家办公?

使用win10专业版自带远程桌面公司内网电脑 文章目录 使用win10专业版自带远程桌面公司内网电脑 在现代社会中&#xff0c;各类电子硬件已经遍布我们身边&#xff0c;除了应用在个人娱乐场景的消费类电子产品外&#xff0c;各项工作也离不开电脑的帮助&#xff0c;特别是涉及到数…

09. Docker Compose

目录 1、前言 2、安装Docker Compose 2.1、Docker Compose版本 2.2、下载安装 3、初试Docker Compose 3.1、传统方案部署应用 3.2、使用编排部署应用 3.3、其他命令 3.3.1、ps 3.3.2、images 3.3.3、depends_on 3.3.4、scale 4、小结 1、前言 随着应用架构的不段…

Python爬虫异常处理心得:应对网络故障和资源消耗

作为一名专业的爬虫代理&#xff0c;我知道在爬取数据的过程中&#xff0c;遇到网络故障和资源消耗问题是再正常不过了。今天&#xff0c;我将与大家分享一些关于如何处理这些异常情况的心得和技巧。不论你是在处理网络不稳定还是资源消耗过大的问题&#xff0c;这些技巧能够帮…

uniapp微信小程序 401时重复弹出登录弹框问题

APP.vue 登陆成功后&#xff0c;保存登陆信息 if (res.code 200) {uni.setStorageSync(loginResult, res)uni.setStorageSync(token, res.token);uni.setStorageSync(login,false);uni.navigateTo({url: "/pages/learning/learning"}) }退出登录 toLogout: func…

Qt学习:Qt 进程和线程之四,线程实际应用

为了让程序尽快响应用户操作&#xff0c;在开发应用程序时经常会使用到线程。对于耗时操作如果不使用线程&#xff0c;UI 界面将会长时间处于停滞状态&#xff0c;这种情况是用户非常不愿意看到的&#xff0c;我们可以用线程来解决这个问题。 大多数情况下&#xff0c;多线程耗…

离线数仓-项目介绍

1. 系统架构 2. 介绍流程 公司的困难数据的来源 业务日志 Flume采集日志数据 选型 ETL flume内存不够&#xff0c;通过ganglia监控器发现 提高吞吐量&#xff0c;batchSize kafka 高效读写 提高吞吐量 kafka挂了 kafka丢数问题 数据重复问题 数据乱序问题 消费策略…

深度学习部署:FastDeploy部署教程(CSharp版本)

FastDeploy部署教程(CSharp版本) 1. FastDeploy介绍 FastDeploy是一款全场景、易用灵活、极致高效的AI推理部署工具&#xff0c; 支持云边端部署。提供超过 &#x1f525;160 Text&#xff0c;Vision&#xff0c; Speech和跨模态模型&#x1f4e6;开箱即用的部署体验&#xf…