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缓存等都是提升性能的体现。

相关推荐
计算机毕设指导65 分钟前
基于微信小程序的丽江市旅游分享系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·旅游
毕设源码-郭学长6 分钟前
【开题答辩全过程】以 基于python电商商城系统为例,包含答辩的问题和答案
开发语言·python
散峰而望9 分钟前
【算法竞赛】栈和 stack
开发语言·数据结构·c++·算法·leetcode·github·推荐算法
Mr -老鬼10 分钟前
Rust 的优雅和其他语言的不同之处
java·开发语言·rust
网安CILLE11 分钟前
PHP四大输出语句
linux·开发语言·python·web安全·网络安全·系统安全·php
weixin_5316518113 分钟前
Rust 的所有权机制
java·开发语言·rust
江公望17 分钟前
QT/QML qmlRegisterType()函数浅谈
开发语言·qt
foundbug99919 分钟前
MATLAB中实现信号迭代解卷积功能
开发语言·深度学习·matlab
Seven9725 分钟前
SPI机制:服务扩展的核心技术
java