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

2025年3月22日 | 阅读 3 分钟

在编写任何应用程序时,String 是一种不可避免的变量类型。String 引用用于存储各种属性,如用户名、密码等。在 Java 中,String 对象是不可变的。不可变简单地意味着不可修改或不可更改。

一旦 String 对象创建,它的数据或状态就不能改变,但会创建一个新的 String 对象。

让我们通过以下示例来理解不可变的概念

Testimmutablestring.java

输出

Sachin

现在可以通过下图来理解。这里 Sachin 没有改变,而是创建了一个带有 Sachin Tendulkar 的新对象。这就是 String 被称为不可变的原因。

Immutable String in Java

如上图所示,创建了两个对象,但 s 引用变量仍然指向“Sachin”,而不是“Sachin Tendulkar”。

但是如果我们明确地将其赋值给引用变量,它将指向“Sachin Tendulkar”对象。

例如

Testimmutablestring1.java

输出

Sachin Tendulkar

在这种情况下,s 指向“Sachin Tendulkar”。请注意,Sachin 对象仍然没有被修改。

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

因为 Java 使用 String 字面量概念。假设有 5 个引用变量,它们都指向一个对象“Sachin”。如果一个引用变量改变了对象的值,那么所有引用变量都会受到影响。这就是为什么 Java 中的 String 对象是不可变的。

以下是 String 的一些特性,这些特性使得 String 对象不可变。

1. 类加载器(ClassLoader)

Java 中的 ClassLoader 使用 String 对象作为参数。考虑一下,如果 String 对象是可修改的,那么值可能会改变,并且应该加载的类可能会不同。

为了避免这种误解,String 是不可变的。

2. 线程安全

由于 String 对象是不可变的,我们不必关心在多个线程之间共享对象时所需的同步。

3. 安全性

正如我们在类加载中看到的那样,不可变的 String 对象通过加载正确的类来避免进一步的错误。这使得应用程序更加安全。考虑一个银行软件的例子。用户名和密码不能被任何入侵者修改,因为 String 对象是不可变的。这可以使应用程序更加安全。

4. 堆空间

String 的不可变性有助于最小化堆内存的使用。当我们尝试声明一个新的 String 对象时,JVM 会检查该值是否已存在于 String 池中。如果存在,则将相同的值分配给新对象。此功能允许 Java 有效地利用堆空间。

为什么 Java 中的 String 类是 Final 的?

String 类是 final 的原因是,没有人可以覆盖 String 类的方法。这样,它可以为新的 String 对象和旧的 String 对象提供相同的功能。