资讯动态

一篇文章彻底搞懂 MySQL 和 Redis:原理、区别、项目用法全解析(建议收藏)

发布时间:2026/8/17 22:39:01 来源:尧图企业网站定制
String 不可变的底层实现String 的不可变性本质是通过底层数据结构 访问控制 设计约束三重保障实现的先看核心源码简化版public final class String {// 存储字符串的核心数组被final修饰一旦赋值就不能指向新数组private final char[] value;// 缓存字符串的哈希值不可变才能保证哈希值永久有效private int hash;// 构造方法只能初始化value数组无法在外部修改public String(char value[]) {this.value Arrays.copyOf(value, value.length);}// 看似修改字符串的方法如substring、replace实际都是返回新String对象public String substring(int beginIndex) {// 内部创建新的char数组封装成新String返回return new String(Arrays.copyOfRange(value, beginIndex, value.length));}}关键实现细节value 数组被 private final 修饰private 保证外部无法直接访问final 保证 value 引用一旦指向某个char数组就不能再指向新的数组没有提供修改 value 数组的方法String 类中没有 setCharAt()、modify() 这类修改数组元素的方法所有看似“修改”的方法如 replace、substring本质都是创建新的 String 对象String 类被 final 修饰防止子类继承并篡改其不可变的特性。补充JDK 9 后 String 底层由 char[] 改为 byte[]节省内存但不可变的核心逻辑完全不变。2. String 设计成不可变的核心原因Java 团队这样设计不是“为了不可变而不可变”而是为了满足性能、安全、并发等核心需求1实现字符串常量池String Pool节省内存字符串常量池是 JVM 为了复用字符串而设计的缓存区域存储在堆中。不可变保证当你创建 String s1 abc 后JVM 会把 abc 存入常量池后续创建 String s2 abc 时直接复用常量池中的对象无需新建。如果 String 可变修改 s1 的值会导致 s2 也被篡改常量池就失去了存在的意义。代码示例public class StringImmutableDemo {public static void main(String[] args) {String s1 abc;String s2 abc;// 指向常量池中的同一个对象System.out.println(s1 s2); // 输出true// 看似修改实际是创建新对象String s3 s1.concat(d);System.out.println(s1); // 输出abc原对象未变System.out.println(s3); // 输出abcd新对象}}2保证哈希值的稳定性提升哈希表性能String 是 HashMap、HashSet 等哈希表最常用的键Key而哈希表依赖 hashCode() 实现快速查找不可变保证String 的 hashCode() 会缓存第一次计算的哈希值源码中的 hash 变量后续无需重复计算大幅提升效率如果 String 可变修改字符串内容会导致哈希值变化哈希表中已存储的键会“丢失”破坏哈希表的正常工作。3保证多线程安全不可变对象天生是线程安全的多个线程同时访问同一个 String 对象时无需加锁因为它的内容永远不会被修改不会出现“一个线程修改、另一个线程读取到脏数据”的问题如果 String 可变多线程操作时必须加锁会大幅增加并发编程的复杂度。4提升安全性String 常用来存储敏感信息如密码、URL、数据库连接串不可变性能避免这些信息被意外篡改例如传递一个 String 类型的密码到某个方法时不用担心方法内部修改这个密码的值如果 String 可变恶意代码可能篡改字符串内容引发安全漏洞。3. 常见误区澄清误区1String s a; s b; 是修改了字符串? 错误这只是把变量 s 的引用从常量池中的 a 指向了 b原对象 a 本身没有任何变化依然存在于常量池中。误区2可以通过反射修改 String 的 value 数组? 理论上可以但这是非常规操作会破坏 String 的不可变约定实际开发中绝对禁止这样做会导致常量池、哈希缓存等机制失效。总结String 不可变的底层是final 修饰的类 private final 的字符数组 无修改数组的方法设计成不可变的核心目的支撑字符串常量池节省内存、缓存哈希值提升性能、保证线程安全和数据安全所有看似“修改”字符串的方法如 replace、concat本质都是返回新的 String 对象原对象始终不变。忧稍侄钩

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价