1、在Java中,String类是不可变类,一个不可变类是一个简单的类,并且这个的实例也不能被修改,
这个类的实例创建的时候初始化所有的信息,并且这些信息不能够被修改
2、字符串常量池
字符串常量池是方法区中一块特殊的存储区域,当创建一个字符串常量的时候,判断该字符串字在符串字符串常量池中是否已经存在
如果存在,返回已经存在的字符串的引用;如果不存在,则创建一个新的字符串常量,并返回其引用
String string1 = "abcd";
String string2 = "abcd";
变量string1,string2指向常量池中的同一个字符串常量对象;如果String是可变的,给一个变量重新赋值一个引用,将会指向错误的值
3、缓存哈希值
在Java中字符串的哈希值会经常被使用到。例如在HashMap中,String的不可变总能保证哈希值总是相等的,并且缓存起来,不用担心会改变,
那意味着不需要每次都计算哈希值,这样会提高效率。在String类中有以下的代码:
private int hash; //用来缓存哈希值
3、促进其他对象的使用
HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));
for(String a: set)
a.value = "a";
在上述代码中,如果String是可变的,那么它的值会被改变,但是这违背了Set集合元素不能重复的设计
4、安全性
String被作为参数广泛的在 Java 类中、网络连接中、和文件操作中使用,如果字符串可变,那么在这些模块中,将会引发严重的安全性问题
boolean connect(string s){
if (!isSecure(s)) {
throw new SecurityException();
}
//here will cause problem, if s is changed before this by using other references.
causeProblem(s);
}
5、不可变的对象同样是线程安全的
因为不可变的对象不能被改变,他们可以在多个线程中共享,就不需要使用线程的同步操作
总之,把String设计为不可变,是为了提高效率和安全性。在广泛的设计开发中,不可变类是首要选择。
来源:oschina
链接:https://my.oschina.net/u/4263213/blog/3793941