温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java String 为啥不可变

发布时间:2026-09-15 05:01:15 来源:亿速云 阅读:87 作者:小樊 栏目:编程语言

在 Java 中,String 被设计为不可变(immutable),主要有以下几方面原因(既和语言设计有关,也和实现机制有关):


一、什么是“不可变”

不可变指的是:
一旦 String 对象被创建,它里面的字符内容就不能被修改
任何“修改”操作(如 substringreplaceconcat)都会创建一个新的 String 对象,而不是改原对象。

String s = "abc";
s = s + "d"; // 实际是创建了新对象 "abcd"

二、为什么 Java 要把 String 设计成不可变

1️⃣ 字符串常量池(String Pool)需要不可变

Java 为了节省内存,使用了 字符串常量池

String a = "abc";
String b = "abc";
// a 和 b 指向同一个对象

如果 String 可变:

a改变 -> b也被改变

这会引发严重的逻辑错误,所以必须不可变


2️⃣ 线程安全(Thread Safety)

不可变对象:

  • 天生线程安全
  • 不需要加锁
  • 可以在多个线程间安全共享
String s = "hello";
// 多线程同时使用 s,不会有问题

如果可变,就需要额外的同步控制。


3️⃣ 缓存 hashCode(性能优化)

String 常被用作 HashMap 的 key。

public int hashCode() {
    // 只计算一次并缓存
}

因为不可变:

  • hashCode 永远不变
  • 可以安全缓存,提高性能

如果可变,作为 key 时会导致哈希混乱。


4️⃣ 安全性(Security)

很多核心 API 都依赖 String

  • 类名加载
  • 文件路径
  • 网络地址
  • 数据库连接

例如:

File file = new File("/data/a.txt");

如果 String 可变,攻击者可能在传递过程中修改路径,造成安全问题。


5️⃣ 类加载机制依赖不可变

JVM 在加载类时:

Class.forName("com.xxx.Test")

如果类名字符串可变,类加载器会变得非常不安全。


三、String 为什么“技术上”不可变?

在 JDK 源码中(简化):

public final class String {
    private final char value[]; // JDK 8 及以前
    // 或
    private final byte value[]; // JDK 9 以后
}

关键点:

  • final class:不能被继承
  • private final value[]:外部无法修改
  • 不提供修改内部数组的方法

四、那为什么还能“感觉”在改?

String s = "a";
s += "b";

实际过程是:

  1. 创建 "a"
  2. 创建 "ab"
  3. s 指向新对象

✅ 对象没变
❌ 变量引用变了


五、对比:可变字符串

Java 也提供了可变方案:

StringBuilder
StringBuffer(线程安全)

适合大量拼接场景。


一句话总结

Java 的 String 不可变,是为了安全性、性能、线程安全和字符串池机制,这是 Java 语言设计上的核心权衡。

如果你愿意,我也可以:

  • 画内存图解释
  • 对比 String / StringBuilder
  • 讲 JDK 9 对 String 的底层优化
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI