1.我们首先要了解在JVM中一个String对象是如何存储的
这是JDK1.8中String源码部分截图
我们以String str = new String(“hello”); 为例观察其存储过程
先在常量池中查找有没有“hello”,没有才创建,然后在堆中开辟空间指向常量池中的地址
注意:String实际上是以字符数组的形式存进去的
2.为什么String是不可变的?
网上部分人说是因为value被final修饰,所以String不可变。这种说法是错误的。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。
final只能表明value不能修改其指向,value是可以修改的。
public static void main(String[] args) {
final int array[] = {1,2,3,4,5};
System.out.println("修改前:"+Arrays.toString(array));
array[0] = 100;
System.out.println("修改后:"+Arrays.toString(array));
}
真正导致String不可变的原因是value被private修饰并且String没有提供相应的get或set,这才导致String不可变。
所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。
3.为什么 String 要设计成不可变的?
- 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
- 不可变对象是线程安全的.
- 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中