原文链接:
http://www.programcreek.com/2013/04/why-string-is-immutable-in-java/
String是Java中的一个immutable类。immutable类意味着该类的实例将无法被修改。该实例中的所有信息在其被创建时就已经被完全初始化,同时之后也无法再作修改。对于immutable类而言,其有很多优点。
1)字符串常量池的要求
字符串常量池一个方法区中一个特殊存储区域。当一个String被创建,并且该String在常量池中已经存在,则这个已经存在的String常量引用将会被返回给该String,而不需要再重新创建一个新的String实例。
下面这段代码在堆中只会创建一个String实例:
这里是内存存储的大致示意图:String string1 = "abcd"; String string2 = "abcd";
如果String不是immutable的,改变其中一个String的引用,将会造成另一个变量引用出错。
2)HashCode
String类型的hashCode 在Java中是普遍存在的(见
《Java String的hashCode
实现
》
),如HashMap,Object等。immutable可以保证hashcode始终相同,因此可以不用担心key值的改变,方便键值对的存储。immutable,这也意味着不需要每次使用时都对hashcode进行计算,提高了运行效率。
在String类中,有如下代码:
private int hash;//this is used to cache hash code.
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是可修改的,它的value可以被任意修改,那么这将未被set被设计的初衷(因为set中是不允许有重复元素出现的,String若可修改,则会造成该情况发生)。(注:前面代码仅是为了演示,真正的String类型中并没有value变量)。
4)安全性
String在Java类中广泛地作为参数进行使用,比如,网络连接,打开文件等。如果String可修改,一个connection或者file将会被改变,而这将有可能造成严重的后果。同时mutable的String类同样也会对反射(Reflection)造成严重的后果,因为其使用的参数也都是String类型的。
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)Immutable类具有多线程安全性
因为immutable实例不可被修改,则它们就能够在多线程中实现安全共享,这在实现多线程同步中是很重要的。
6)String设计成final,也有利于Java将其优化成内联函数,提高虚拟机效率。
总而言之,将String设计成immutable是处于效率和安全性方面的考虑,这也是immutable类在使用中的共通优点。