java基础之String的不可变性

目录

概述

String是如何实现不可变的

String为何设计成不可变的

1.缓存和性能优化

2.安全性

3.线程安全性

4.API设计和预测性能


概述

String类的不可变性意味着一旦创建了一个字符串对象,它的值就不能被修改。

String是如何实现不可变的

查看源码

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {// 字符数组value用于存储字符序列private final char value[];// substring方法返回一个新的String对象public String substring(int beginIndex) {if (beginIndex < 0 || beginIndex > value.length) {throw new StringIndexOutOfBoundsException(beginIndex);}int subLen = value.length - beginIndex;if (subLen < 0) {throw new StringIndexOutOfBoundsException(subLen);}return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);}// concat方法用于连接字符串并返回一个新的String对象public String concat(String str) {int otherLen = str.length();if (otherLen == 0) {return this;}int len = value.length;char buf[] = Arrays.copyOf(value, len + otherLen);str.getChars(buf, len);return new String(buf, true);}
}

1.String类被声明为final,这意味着它不能被继承。那么他里面的方法就是没办法被覆盖的。


2.用final修饰字符串内容的char[] (从JDK 1.9开始,char[]变成了byte[]),由于该数组被声明为final,一旦数组被初始化,就不能再指向其他数组


3.String类没有提供用于修改字符串内容的公共方法。例如,没有提供用于追加、删除或修改字符的方法。如果需要对字符串进行修改,会创建一个新的String对象。

String为何设计成不可变的

为什么要把String设计成不可变的呢? 有什么好处呢?


这个问题,困扰过很多人,甚至有人直接问过Java的创始人James Gosling。
在一次采访中James Gosling被问到什么时候应该使用不可变变量,他给出的回答是:
I would use an immutable whenever I can(我会尽可能使用不可变的。)


那么,他给出这个答案背后的原因是什么呢? 是基于哪些思考的呢?
其实,主要是从缓存、安全性、线程安全和性能等角度出发的。

1.缓存和性能优化

字符串是使用最广泛的数据结构。大量的字符串的创建是非常耗费资源的,所以,Java提供了对字符串的缓存功能,可以大大的节省堆空间。
JVM中专门开辟了一部分空间来存储Java字符串,那就是字符串池
通过字符串池,两个内容相同的字符串变量,可以从池中指向同一个字符串对象,从而节省了关键的内存资源。

String s="abcd";
String s2=s1;

对于这个例子,s和s2都表示"abcd",所以他们会指向字符串池中的同一个字符串对象.

但是,之所以可以这么做,主要是因为字符串的不变性。试想一下,如果字符串是可变的,我们一旦修改了s的内容,那必然导致s2的内容也被动的改变了,这显然不是我们想看到的。

缓存HashCode。由于字符串的不可变性,可以将字符串的哈希码(HashCode)缓存起来,这样在多次使用字符串的哈希码时就不需要重新计算,提高了性能。

2.安全性

String对象在Java中广泛用于存储敏感信息,例如密码、数据库连接等。如果String是可变的,那么它的值可以被修改,这可能导致潜在的安全漏洞。通过将String设计为不可变的,可以确保其值在创建后不能被修改,提高了数据的安全性。

3.线程安全性

不可变会自动使字符串成为线程安全的,因为当从多个线程访问它们时,它们不会被更改。
因此,一般来说,不可变对象可以在同时运行的多个线程之间共享。它们也是线程安全的,因为如果线程更改了值,那么将在字符串池中创建一个新的字符串,而不是修改相同的值。因此,字符串对于多线程来说是安全的。

4.API设计和预测性能

String的不可变性使得它的API设计更加简单和一致。在使用String时,我们可以放心地传递和接收String对象,不必担心它的值会被修改。此外,不可变性还使得String的哈希值和相等性判断可以预先计算,提高了这些操作的性能。

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

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

相关文章

FreeRTOS 实时操作系统第八讲 - 时间管理 (系统节拍,延时函数)

一、系统节拍 FreeRTOS 实时操作系统需要一个时钟节拍&#xff0c;以供系统处理诸如延时、超时、软件定时器等与时间相关的事件。 时钟节拍是周期性定时中断&#xff0c;这个中断可以看做是系统心跳。中断时间间隔取决于不同的应用&#xff0c;一般是 1ms – 100ms。时钟的节拍…

将“渴望“乐谱写入AT24C02并读出播放

#include <reg51.h> // 包含51单片机寄存器定义的头文件 #include <intrins.h> //包含_nop_()函数定义的头文件 #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写…

Winclone Pro 10 for Mac:轻松备份和还原你的Windows系统

Winclone Pro 10 for Mac是一款专为Mac用户设计的备份和还原软件&#xff0c;旨在帮助用户轻松管理和保护他们的Windows系统。无论是为了数据安全还是系统的稳定性&#xff0c;Winclone Pro 10都能提供全面的解决方案。 这款软件具备强大的备份功能&#xff0c;能够快速而准确…

【Transformer】深入理解Transformer模型2——深入认识理解(下)

前言 Transformer模型出自论文&#xff1a;《Attention is All You Need》 2017年 近年来&#xff0c;在自然语言处理领域和图像处理领域&#xff0c;Transformer模型都受到了极为广泛的关注&#xff0c;很多模型中都用到了Transformer或者是Transformer模型的变体&#xff0…

【LeetCode每日一题】1185.一周中的第几天(模拟+调用库函数:三种方法)

2023-12-30 文章目录 一周中的第几天方法一&#xff1a;模拟思路步骤 方法二&#xff1a;调用库函数方法三&#xff1a;调用库函数 一周中的第几天 ​ 提示&#xff1a;给出的日期一定是在 1971 到 2100 年之间的有效日期。 方法一&#xff1a;模拟 思路 1.可以根据1970年的…

多输入多输出 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入多输出预测

多输入多输出 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入多输出预测 目录 多输入多输出 | MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入多输出预测预测效果基本介绍模型背景程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN麻雀算法优化卷积神经网络多输入…

1.2.0 IGP高级特性之FRR

理论部分参考文档&#xff1a;Segment Routing TI-LFA FRR保护技术 - 华为 一、快速重路由技术 FRR(Fast Reroute)快速重路由 实现备份链路的快速切换&#xff0c;也可以与BFD联动实现对故障的快速感知。 随着网络的不断发展&#xff0c;VoIP和在线视频等业务对实时性的要求越…

海康visionmaster-Group 循环:获取 Group 循环数 据结果的方法

如何获取 Group 循环的所有数据结果&#xff1f; 解答 在 Group 中使用数据集合模块&#xff0c;然后在 Group 的输出设置订阅数据集合模块相关结果&#xff0c;最后在二次开发中获取 Group 的数据结果。如下图所示&#xff0c;参数 out1 为 Group 订阅的数据集合&#xff0c;在…

Vue2中使用echarts,并从后端获取数据同步

一、安装echarts npm install echarts -S 二、导入echarts 在script中导入&#xff0c;比如&#xff1a; import * as echarts from "echarts"; 三、查找要用的示例 比如柱状图 四、初始化并挂载 <template><div id"total-orders-chart" s…

07-C++ 异常

异常 1. 概念 异常事件&#xff08;如&#xff1a;除 0 溢出&#xff0c;数组下标越界&#xff0c;所要读取的文件不存在,空指针&#xff0c;内存不足等等&#xff09; 在C 语言对错误的处理是两种方法&#xff1a; 一是使用整型的 返回值标识错误&#xff1a;二是使用 errno…

分享一个学习Typescript最全的Github网站

一个专注研究Typescript的网站&#xff0c;&#x1f396;&#x1f396;&#x1f396;在这里你可以全面深入学习Typescript相关知识,通过动画方式讲解TS&#xff0c;还有很多常见问题解答。你还可以挑战相应的题目&#xff0c;快来学习吧 我就懒一点&#xff0c;直接原滋原味的…

Django学习3——靓号管理

目录 靓号管理 表结构和数据 根据表结构的需求&#xff0c;在models.py中创建类&#xff08;由类生成数据库中的表&#xff09; 在数据库生成表 自己在数据模拟创建一些数据&#xff1a; 靓号列表 新建靓号 编辑靓号 删除靓号 搜索靓号 靓号管理 表结构和数据 根…