不可变的含义:
字符串的不可变性意味着一旦创建,字符串的值就不能被改变。每当对字符串执行操作(例如拼接或替换)时,都会生成一个新的字符串对象。
为什么不可变:
String的内部数据是一个char数组,是对字符串数组的封装,并且是被final修饰的,创建后不可改变。
不可变的好处:
1.便于实现字符串池
在Java中,由于会大量的使用String常量,如果每一次声明一个String都创建一个String对象,那将会造成极大的空间资源的浪费。Java提出了String pool的概念,在堆中开辟一块存储空间String pool,当初始化一个String变量时,如果该字符串已经存在了,就不会去创建一个新的字符串变量,而是会返回已经存在了的字符串的引用。
2.使多线程安全
由于字符串对象的内容无法被修改,这意味着多个线程可以安全地访问相同的字符串实例,而无需额外的同步机制来保护数据的一致性。这种特性带来以下优势:
首先,不可变字符串消除了竞态条件(race condition)的可能性。多线程环境下,如果多个线程同时对可变对象进行读写操作,可能会导致数据不一致或意外的结果。但是,由于字符串不可变,多个线程可以自由地读取相同的字符串实例,不会出现线程之间的数据竞争问题。
其次,不可变性使得字符串在多线程环境下可以安全地共享。在Java中,字符串常量池允许相同的字符串常量在内存中只存在一份实例。这意味着多个线程可以引用并共享相同的字符串对象,而无需担心其中一个线程会修改它,从而保证了线程安全性。
3.加快字符串处理速度
不可变性还为字符串的缓存和优化提供了机会。由于字符串的值在创建后不会改变,可以在创建时计算并缓存其哈希码、长度等属性,以提高性能和效率。
由于String是不可变的,保证了hashCode的唯一性,于是在创建对象时其hashCode就可以放心的缓存了,不需要重新计算。这也就是一般将String作为Map的Key的原因,处理速度要快过其它的键对象。所以HashMap中的键往往都使用String。
String的字符数据可变
String类使用char value[]来存字符数据,它的类型为:private final char value[];
看上去它是不可更改的,因为是final类型。注意:final只是表示不能指向其他地址,它里边的内容是可以更改的。
结论:String是可以更改的,使用反射,value.setAccessible(true),然后修改它即可。