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

目录

缓存

安全性

线程安全

hashCode缓存

性能


其实这个问题我们可以通过缓存、安全性、线程安全和性能几个维度去解析。

缓存

字符串是Java最常用的数据结构,我们都知道字符串大量创建是非常耗费资源的,所以Java中就将String设计为带有缓存的功能,可以大大节省堆空间。

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

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

java 复制代码
String s1 = "abc";
String s2 = "abc";

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

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

安全性

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

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

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

但是,如果是可变的,那么这个字符串内容就可能随时都被修改。那么这个字符串内容就完全不可信了。

线程安全

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

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

hashCode缓存

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

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

性能

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

相关推荐
周某某~5 分钟前
五.建造者模式
java·设计模式·建造者模式
YuTaoShao7 分钟前
Java八股文——Spring「SpringMVC 篇」
java·开发语言·spring
罗迪尼亚的熔岩8 分钟前
在C# 中使用建造者模式
java·c#·建造者模式
vortex515 分钟前
Yakit 热加载入门学习指南
java·服务器·前端
程序员JerrySUN17 分钟前
Linux 内存管理实战精讲:核心原理与面试常考点全解析
linux·运维·开发语言·嵌入式硬件·架构
CodeWithMe18 分钟前
【C/C++】long long 类型传参推荐方式
c语言·开发语言·c++
程序员岳焱25 分钟前
深入解析Spring AI:Java生态中的AI集成利器
java·人工智能·openai
ch_s_t30 分钟前
Babylon.js引擎(二)
开发语言·javascript·ecmascript
北京_宏哥31 分钟前
🔥《刚刚问世》系列初窥篇-Java+Playwright自动化测试-19- 操作鼠标悬停(详细教程)
java·前端·测试
张小洛31 分钟前
构建高效开发节奏:我的IDEA休息提醒插件实践
java·ide·intellij-idea