漫画版:为什么Java里面的String对象是不可变的?

Java中的String是可变的吗?为什么? Java中的String类是不可变的,这种设计带来了多方面的好处,包括安全性、线程安全、性能优化以及字符串池的实现。不可变对象的设计使得字符串在Java中成为一个非常高效和可靠的数据类型。尽管在某些场景下需要额外的优化措施,例如使用进行字符串拼接,但总体而言,不可变性为Java程序提供了很多重要的优势。通过理解这些细节,开发者可以更好地利用String类的特性,编写出高效且安全的代码。 阅读详情

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

 

String的不变性

String在Java中特别常用,相信很多人都看过他的源码,在JDK中,关于String的类声明是这样的:

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
}

可以看到,String类是final类型的,那么也就是说,String是一个不可变对象。

不可变对象是在完全创建后其内部状态保持不变的对象。这意味着,一旦对象被赋值给变量,我们既不能更新引用,也不能通过任何方式改变内部状态。

可是有人会有疑惑,String为什么不可变,我的代码中经常改变String的值啊,如下:

String s = "abcd";
s = s.concat("ef");

这样,操作,不就将原本的"abcd"的字符串改变成"abcdef"了么?

但是,虽然字符串内容看上去从"abcd"变成了"abcdef",但是实际上,我们得到的已经是一个新的字符串了。

漫画:为什么Java里面的String对象是不可变的?

 

如上图,在堆中重新创建了一个"abcdef"字符串,和"abcd"并不是同一个对象。

所以,一旦一个string对象在内存(堆)中被创建出来,他就无法被修改。而且,String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。

如果我们想要一个可修改的字符串,可以选择StringBuffer 或者 StringBuilder这两个代替String。

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

为什么String要设计成不可变

在知道了"String是不可变"的之后,大家是不是一定都很疑惑:为什么要把String设计成不可变的呢?有什么好处呢?

这个问题,困扰过很多人,甚至有人直接问过Java的创始人James Gosling。

在一次采访中James Gosling被问到什么时候应该使用不可变变量,他给出的回答是:

I would use an immutable whenever I can.

那么,他给出这个答案背后的原因是什么呢?是基于哪些思考的呢?

其实,主要是从缓存、安全性、线程安全和性能等角度出发的。

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

缓存

字符串是使用最广泛的数据结构。大量的字符串的创建是非常耗费资源的,所以,Java提供了对字符串的缓存功能,可以大大地节省堆空间。

JVM中专门开辟了一部分空间来存储Java字符串,那就是字符串池。

通过字符串池,两个内容相同的字符串变量,可以从池中指向同一个字符串对象,从而节省了关键的内存资源。

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

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

漫画:为什么Java里面的String对象是不可变的?

 

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

安全性

字符串在Java应用程序中广泛用于存储敏感信息,如用户名、密码、连接url、网络连接等。JVM类加载器在加载类的时也广泛地使用它。

因此,保护String类对于提升整个应用程序的安全性至关重要。

当我们在程序中传递一个字符串的时候,如果这个字符串的内容是不可变的,那么我们就可以相信这个字符串中的内容。

但是,如果是可变的,那么这个字符串内容就可能随时都被修改。那么这个字符串内容就完全可信了。这样整个系统就没有安全性可言了。

线程安全

不可变会自动使字符串成为线程安全的,因为当从多个线程访问它们时,它们不会被更改。

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

hashcode缓存

由于字符串对象被广泛地用作数据结构,它们也被广泛地用于哈希实现,如HashMap、HashTable、HashSet等。在对这些散列实现进行操作时,经常调用hashCode()方法。

不可变性保证了字符串的值不会改变。因此,hashCode()方法在String类中被重写,以方便缓存,这样在第一次hashCode()调用期间计算和缓存散列,并从那时起返回相同的值。

在String类中,有以下代码:

private int hash;//this is used to cache hash code.

性能

前面提到了的字符串池、hashcode缓存等,都是提升性能的提现。

因为字符串不可变,所以可以用字符串池缓存,可以大大节省堆内存。而且还可以提前对hashcode进行缓存,更加高效

由于字符串是应用最广泛的数据结构,提高字符串的性能对提高整个应用程序的总体性能有相当大的影响。

总结

通过本文,我们可以得出这样的结论:字符串是不可变的,因此它们的引用可以被视为普通变量,可以在方法之间和线程之间传递它们,而不必担心它所指向的实际字符串对象是否会改变。

我们还了解了促使Java语言设计人员将该类设置为不可变类的其他原因。主要考虑的是缓存、安全性、线程安全和性能等方面

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

漫画:为什么Java里面的String对象是不可变的?

 

最全学习笔记:大厂真题+微服务+MySQL+分布式+SSM框架+Java+Redis+数据结构与算法+网络+Linux+Spring全家桶+JVM+高并发+各大学习思维脑图+面试集合

Response Instance 详解:在 ABAP OData Client Proxy 中读懂每一次响应 ABAP OData Client Proxy中的Response Instance是关键信息载体,封装了业务数据及调用上下文(如分页、delta link等)。响应实例在执行请求后自动生成,根据请求类型返回特定接口(如READ返回/IWBEP/IF_CP_RESPONSE_READ)。响应抽象与OData版本解耦,支持统一处理V2/V4服务。常见响应类型包括单实体读取、列表读取(支持分页和增量同步)、创建/更新/删除响应等。开发时可通过响应对象的安全类型方法获取数据,如get_business_data获 阅读详情

相关推荐

Qt绘图库对决:QWT与QCustomPlot的实战选型指南

本文为Qt开发者提供了QWT与QCustomPlot两大绘图库的实战选型指南。文章从功能特性、性能资源、开发效率三大维度进行深度对比,并结合工业监控、科学计算、嵌入式设备等典型场景,给出了清晰的决策清单。对于需要专业科学图表(如极坐标、等高线图)的场景推荐QWT;对于追求高性能、实时性、快速开发及嵌入式部署的通用图表需求,QCustomPlot是更优选择。

alpha的博客 244

string的特点

1.不变性 不变性是指String对象一旦生成,则不能再对它进行改变。String的这个特性可以泛化成不变(immutable)模式,即一个对象的状态在对象被创建之后就不再发生变化。不变模式的主要作用在于,当一个对象需要被多线程共享,并且访问频繁时,可以省略同步和锁等待的时间,从而大幅提高系统性能。 注意:不变性可以提高多线程访问的性能。因为对象不可变,因此对于所有线程都是只读的,多线程访问时,即使不加同步也不会产生数据的不一致,故减小了系统开销。 由于不变性,一些看起来像是修改的操作,实际上都是依靠产生新

Alaotianhuifei的博客 1462

HFSS实战:手把手教你设计一款小型化圆极化微带天线(附仿真文件)

本文详细介绍了使用HFSS设计小型化圆极化微带天线的完整流程,包括工程初始化、辐射贴片设计、仿真设置与优化等关键步骤。通过实战案例,帮助工程师掌握圆极化天线设计技巧,解决轴比控制和耦合馈电匹配等核心问题,适用于物联网终端和便携式设备应用。

weixin_32770423的博客 340

爆炸新闻!一失足少女白天学习Java,晚上工作突然一天摇身一变成某大老

String的不变性 String在Java中特别常用,相信很多人都看过他的源码,在JDK中,关于String的类声明是这样的: public final class String implements java.io.Serializable, Comparable<String>, CharSequence { } 可以看到,String类是final类型的,那么也就是说,String是一个不可变对象。 不可变对象是在完全创建后其内部状态保持不变的对象。这意味着,一旦对象...

weixin_55932015的博客 292

论文理解【LLM-OR】——【OptiMUS】Scalable Optimization Modeling with (MI)LP Solvers and Large Language Models

OptiMUS 把“自然语言→优化建模与求解”从单次生成改造成“结构化问题 + 多智能体协作 + 连接图检索”的模块化流程,并在更长更难的数据集上验证了这种结构化方法相对端到端 prompting 的优

佚失的诗篇 829

python实现ECMS算法

ECMS(Equivalent Consumption Minimization Strategy)算法是一种用于混合动力汽车能量管理系统的优化策略。它通过计算等效油耗来平衡电池电量消耗和燃油消耗,从而优化整体能耗。以下是一个简单的Python实现,用于演示ECMS算法的基本思想。这个实现假设了一个简单的混合动力汽车模型,其中电池电量和燃油消耗是主要的优化目标。

weixin_45570158的博客 924

为什么String在java中是不可变的?

这句代码执行过之后,又创建了一个新的对象“123456”, 而引用 s 重新指向了这个新的对象,原来的对象“ABCabc”还在内存中存在,并没有改变。引用只是一个 4 字节的数据,里面存放了它所指向的对象的地址,通过这个地址可以访问对象。可以反射出 String 对象中的 value 属性,进而改变通过获得的 value 引用改变数组的结构。在 Java 中,String 类是不可变的,即 String 中的对象是不可变的。的,和第四条:使所有的域都是私有的。修饰的,满足了第二条的:类不能被拓展。

黑马程序员官方博客 962

Unity ProBuilder(自己创建斜面、拐角)

ProBuilder基础实例

weixin_56537692的博客 1551

Java中的String类---不可变的字符串

String类作为Java中重要的内置类,以其不可变性和字符串池等特性,在字符串处理方面具有重要的优势。它的不可变性保证了字符串对象的安全性和线程安全性,同时也提高了性能,避免了频繁创建对象的开销。在实际编码中,需要注意字符串的不可变性特性,避免不必要的字符串拼接和操作,以提高性能和代码质量。通过对String类的探索,我们更深入地了解到了Java中字符串的特性和操作方法。在日常开发中,合理利用和理解String类的特性,我们能够更加灵活高效地处理字符串,提升我们代码的质量和性能。

南 阳 的博客 890

史上最全的Logisim存储系统实验教程(基于华中科技大学计算机组成原理实验)内赋源码下载

本博客是最全的最好的解释的华中科技大学计算机组成实验存储系统实验,本博客给出了电路实现,也给出了使用电路的原因有利于新手学习十分详细。并且内赋源码下载。

qq_62325622的博客 2万+

别再自己造轮子了!用MONAI Model Zoo里的预训练模型,5分钟搞定医学影像AI项目

本文介绍了如何利用MONAI Model Zoo中的预训练模型快速搭建医学影像AI项目,大幅节省开发时间和计算资源。通过实战案例展示了UNet、DenseNet121等核心模型的应用技巧,帮助临床医生和研究者5分钟内启动高质量医学影像分析,特别适合小样本场景下的病灶分割和分类任务。

weixin_33704234的博客 240

String 为什么是不可变的

String 对象的不可变指的是,任何对于 String 对象的操作不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。Java 关于 String 的源码如下: String 类是用关键字 final 修饰的,使得 String 类不可被继承,进而避免了破坏 String 类的不可变。成员变量 value 是用 final 修饰的,保证了 value 的引用地址不可变,但是里面的具体元素是可以被改变的。看下面这个例子: 编译器不允许我们直接讲 value 指向堆区的另一个地址,但是如果我们直接对

xinyun2699的博客 1万+

MC_SetOverride指令详细应用介绍(基恩士PLC)

基恩士KV系列PLC和松下总线绝对值伺服运动控制(详细配置+轴控完整ST源代码)

RXXW_Dor的博客 336

JAVA String类为什么是Final不可变的

为什么?为什么? 原因: 1、因为要实现字符串池 什么是字符串池:java中的字符串池是存储在Java堆内存中的字符串池 如果你觉得抽象,那就举个栗子:字符串池就像一个公共的大相册,每一个字符串就是一张照片,当你需要哪张照片的时候,发现相册里有这张照片,就可以直接拿过来用。当相册中没有你想要的照片,你可以自己生成照片,然后把照片放到相册中,自己和其他人都可以拿来用了。 2、为了线程安全 3、为了实现String可以创建HashCode不可变性 我们先来看一下String的源码 可以...

qq_39914899的博客 2459

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java中的String为什么是不可变的? -- String源码分析

什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。 区分对象和对象的引用 对于Java初学

昨夜星辰的博客 7万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java - 为什么String在Java中是不可变的?

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 字符串在Java中是不可变的,因为String对象缓存在String池中。由于缓存的字符串在多个客户之间共享,因此始终存在风险,其中一个客户的操作会影响所有其他客户。例如,如果一段代码将String “Test”的值更改为“TEST”,则所有其他客户...

了解➔熟悉➔掌握➔精通 3万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

String为什么不可变,超级容易理解

String为什么不可变,超级容易理解首先我们都知道String是一个不可变对象,那什么是不可变对象呢?新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 首先我们都知道String是一个不可变对象,那什么是不可变对象呢? 一

ssm上传多张图片以及批量插入到数据库 2625

string对象不可变的原理

ps:主要是其内部使用了private final修饰成员,如果想修改,需要使用到反射技术 string方法的修改效果是通过新建StringBuilder来实现的,更老的版本使用StringBuffer,后者是线程安全版本,但效率较低 什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成

cws1214的专栏 4693

为什么Java里面String类是不可变的

在Java里面String类型是不可变对象,这一点毫无疑问,那么为什么Java语言的设计者要把String类型设计成不可变对象呢?这是一个值得思考的问题 Java语言的创建者James Gosling,曾经在一次采访中被人问到:什么时候应该使用不可变对象(immutable object),他回答:任何可以使用的时候都会使用。 在这之前,我们先来简单了解一下,什么是不可变对象? 不可变对象指...

三劫散仙 3055

Java中的String字符串为什么不可变

什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。 区分对象和对象的引用 对于Java初学者, 对

ps_zhanglei的专栏 5084

Java中的String为什么是不可变的?—String源码分析

什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。 区分对象和对象的引用 对于Java

Java干货 4006

Java的string类为什么是不可变的

java String 不可变

liuqinhou的博客 1656

String为什么是不可变的?

我们谈论的String不可变, 指的是字符串的值不可变 1,什么是不可变对象? 如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。 不能改变状态的意思是:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不被指向其他的对象,引 用类型指向的对象的状态也不能改变...

欣欣的博客 4043

Java中的String为什么是不可变的?

       String类是不可变类,一个String对象被创建以后,包含这个对象中的字符串序列是不可改变的。与其问String为什么是不可变的,还不如问String类是如何实现其对象不可变的。 什么是不可变对象?        如果一个对象它被创建后,状态不能改变,则这个对象被认为是不可变的。 String是如何实现其对象不可变?        首先需要补充一个容易混淆的知识点:当使用...

dearKundy的博客 2万+

面试必问:java中String对象为什么要设计成不可变的呢?

这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下。 想要完全了解String,在这里我们需要解决以下几个问题 (1)什么是不可变对象? (2)String如何被设计成不可变对象的? (3)有什么办法能够改变String? (4)JAVA语言为什么把String类型设计成不可变? 带着这些问题就可以开...

冯冬冬的博客 550

Java技术——String类为什么是不可变的

0. 前言 如果一个对象,在它创建完成之后不能再改变它的状态,包括对象内的成员变量、基本数据类型的值等等。那么这个对象就是不可变的。众所周知String类就是不可变的。转载请注明出处:1. String类为什么是不可变的首先看一下String类的源码中://JDK1.6 public final class String implements java.io.Serializab...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 2651
上一篇: 还在搞三层架构?了解下 DDD 分层架构的三种模式吧
下一篇: 100W点击 10w人获取,阿里Java高级面试题及答案 到底有多强
奇迹摘星w
博客等级 码龄6年 1844粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值