1 线程安全
由于String类时不可变的,所以当多线程共享同一个String时,不必担心同步问题。
2 性能
2.1 缓存哈希值
在String类中有一个名为hash的int类型属性,String会用这个hash变量来存储哈希值。
证明:
public static void main(String[] args) {
String s = new String("asa");
int hashcode;
hashcode = s.hashCode();
hashcode = s.hashCode();
}
// hashcode函数源码:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
首先,创建一个String对象,里面的属性value会初始化为0,字符串内容是"asa"。
然后执行第一次hashcode函数
由于hash初始值为0,且String不是空串,所以程序会进入if语句,去计算hash值,for循环结束后,会把计算结果赋给hash变量。
接着第二次调用hashcode函数
可以看到,hash的值是96879,并不为空,且字符串不是空串,所以程序不会进入if语句,而是直接return h,就避免了重复计算hash值。
String缓存哈希机制可以让String类非常适合作为哈希表数据类型的Key,因为计算hash值的速度更快,可以提高Map的存储效率。而这个优秀的机制正是基于String类的不变性。试想,如果String类是可变的,缓存哈希值就没用了,每次都要重新计算,因为说不定字符串内容已经改变了。
2.2 设计字符串常量池
基于String类的不变性,设计出了字符串常量池,该常量池可以让相同内容的字符串共享同一片内存空间,从而达到节约内存的目的。String类中并不会真正存储字符串,而是有一个字符数组引用变量,指向产量池中的某一个字符串。这样,对于两个String类对象,如果他们的字符串内容相同,虽然在堆中的内存地址不同,但是他们value属性指向的是同一个字符串常量。