String类为什么是不可变类

为什么说String对象一旦创建,其值是不可修改的

在Java中将String设计成不可变的是综合考虑到各种因素的结果,需要综合考虑内存、同步、数据结构以安全方面的考虑。

String被设计成不可变的主要目的是为了安全和高效(效率)。

1)字符串常量池的需要(共享性)

字符串常量池是Java堆内存中的一个特殊的存储区域,当创建一个String对象时,假如此字符串值已经在常量池中,则不会创建新的对象,而是引用已经存在的对象。这样做能够减少 JVM 的内存开销,提高效率

当使用加号(+)连接多个字符串时,由于String是不可变的,每次连接操作都会创建一个新的String对象,这样可以避免频繁修改字符串带来的性能损耗

如下代码所示,将会在堆内存中只创建一个实际的String对象

String str1 = "abcd";
String str2 = "abcd";

比如引用 s1和 s2 都是指向常量池的同一个对象 “abcd”,如果 String 是可变类,引用 str1 对 String 对象的修改,会直接导致引用 str2 获取一个错误的值。这样的话,那么常量池就没有存在的意义了

2)允许String对象缓存HashCode(缓存hash值)

Java中String对象的哈希吗被频繁的使用,比如在HashMap等容器中。

String类的不变性保证了hash码的唯一性,因此可以放心地进行缓存,它的hashcode值在创建时就被计算好并缓存起来,这样可以提高字符串作为HashMap的键时的性能

3)安全性

字符串被许多的Java类库用来当做参数,例如网络连接地址URL、文件路径、反射机制所需要的String参数等,假如String不是固定不变的,将会引起各种安全隐患,它们的值在创建后不能被修改。这有助于确保数据的一致性和可靠性,防止意外的数据修改

不可变对象天生就是线程安全的。

4) 多线程(线程安全)

多线程中,可变对象的值很可能被其他线程改变,造成不可预期的结果。而不可变的 String 可以自由在多个线程之间共享,不需要同步处理,多个线程可以同时访问同一个String对象而无需担心数据竞争问题,从而保证了线程安全性

String是如何设置为不可变的?

  1. 字段使用final修饰:String类中的字符数组byte[] value(jdk1.8是char[] value)被声明为final,表示一旦赋值就不能再改变。

  2. 使用private修饰属性:String类内部的属性都是私有的,外部无法直接修改它们的值。

  3. 不提供setter方法:String类没有提供用于修改字符串内容的公共setter方法。如果需要修改字符串,将会创建一个新的String对象。

  4. 方法返回新实例:对String对象进行任何操作(如拼接、替换等),都会返回一个新的String实例,原始的String对象保持不变。

  5. 静态工厂方法:String类提供了大量静态工厂方法来创建新的String实例,而不是通过公共构造器直接创建实例,这样可以控制String对象的生成过程。

  6. 字符串连接时使用StringBuilder或StringBuffer:在对字符串进行拼接操作时,String类内部并不是直接对原始字符串对象进行修改,而是利用StringBuilder或StringBuffer来处理字符串拼接,最终生成一个新的String对象。

相关推荐

  1. C#面:什么可变字符串

    2024-04-15 09:02:02       34 阅读
  2. IDEA:找String、主

    2024-04-15 09:02:02       35 阅读
  3. static为什么能修饰String

    2024-04-15 09:02:02       37 阅读
  4. 在Python中的什么

    2024-04-15 09:02:02       63 阅读
  5. 【C#语言入门】19. 什么

    2024-04-15 09:02:02       38 阅读
  6. TypeScript中什么类型接口?

    2024-04-15 09:02:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-15 09:02:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-15 09:02:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-15 09:02:02       82 阅读
  4. Python语言-面向对象

    2024-04-15 09:02:02       91 阅读

热门阅读

  1. Qt实现Kermit协议(六)

    2024-04-15 09:02:02       42 阅读
  2. IDE:常见的集成开发环境

    2024-04-15 09:02:02       200 阅读
  3. C语言数组的初始化方法大全

    2024-04-15 09:02:02       34 阅读
  4. 软件测试Linux 必备考点

    2024-04-15 09:02:02       134 阅读
  5. 神州数码交换机基本指令

    2024-04-15 09:02:02       31 阅读