1、字符串常量池
字符串常量池是方法区中一块存储区域,当创建一个字符串常量的时候,判断该字符串字在符串字符串常量池中是否已经存在,只有当字符串是不可变的,字符串池才有可能实现。
如果存在,返回已经存在的字符串的引用;如果不存在,则创建一个新的字符串常量,并返回其引用。
String string1 = "abcd";
String string2 = "abcd";
变量string1,string2指向常量池中的同一个字符串常量对象;如果String是可变的,一个变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。
2、安全性
String被作为参数广泛的在数据库的用户名密码中、网络连接中、和文件操作中使用,如果字符串可变,那么在这些模块中,将会引发严重的安全性问题。因为字符串是不可变的,所以它的值是不可改变的,否则可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。
3、不可变的对象同样是线程安全的
因为不可变的对象不能被改变,他们可以在多个线程中共享,就不需要使用线程的同步操作。同一个字符串实例可以被多个线程共享,这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
4、类加载器
类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。例如想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,则会对数据库造成不可知的破坏。
5、缓存哈希值
因为字符串是不可变的,所以在它创建的时候哈希值就被缓存了,不需要重新计算,这样会提高效率。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
总之,把String设计为不可变,是为了提高效率和安全性。在广泛的设计开发中,不可变类是首要选择。