为什么Java中的String是不可变的?

翻译 2015年11月19日 13:36:19

原文:Why String is immutable in Java ?
翻译:get-set


String是Java中的一个不可变类。所谓不可变,简单来说就是其对象不能被修改。实例中的所有信息在初始化的时候就已经具备,并且不能被修改(老外好啰嗦…)。不可变类有很多优点。这篇文章简要说明了为什么String被设计为不可变类。关于其好的回答应该建立在对内存模型、同步和数据结构等的理解之上。

1. 字符串池的需求

字符串池是一个位于方法区的特殊区域。当一个字符串被创建的时候,如果该字符串已经存在于字符串池中,那么直接返回该字符串的引用,而不是创建一个新的字符串。
下边的代码将只会创建一个字符串对象:

String s1 = "abcd";
String s2 = "abcd";

就不上图了,这块的内容前一篇翻译的文章已经解释过了。也就是s1s2都指向同一个字符串对象。
如果String不是不可变的,那么修改s1的字符串对象同样也会导致s2的内容发生变化。

2. 缓存Hashcode

字符串的hashcode在Java中经常被用到。例如,在一个HashMap中。其不可变性保证了hashcode(哈希值)总是保持不变,从而不用担心因hashcode变化导致的缓存问题。那就意味着,不用每次在其使用的时候计算其hashcode,从而更加高效。
String类中,有如下代码:

private int hash; //用来缓存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是可变的,也就是说set中的值是可变的,这会影响到set的设计(set包含不重复的元素)。当然这个例子是有问题的,在String类中是不存在value这个属性的。

4.安全性

字符串在许多的java类中都用作参数,例如网络连接,打开文件等等。如果字符串是可变的,一个连接或文件就会被修改从而导致严重的错误。可变的字符串也会导致在使用反射时导致严重的问题,因为参数是字符串形式的。
举例如下:

boolean connect(String s) {
    if (!isSecure(s)) {
        throw new SecurityException();
    }
    // 如果s内的值被修改,则会导致出现问题
    doSomethind(s);    
}

(虽然略牵强,但是也有一定道理)

5. 不可变的对象本身就是线程安全的

不可变的对象,可以在多个线程间自由共享。从而免除了进行同步的麻烦。

总之, String被设计为不可变的类,是出于性能和安全性的考虑,这也是其他所有不可变类应用的初衷。


相关文章推荐

为什么String要设计成不可变的?

翻译人员: 铁锚 翻译日期: 2013年11月18日 原文链接: Why string is immutable in Java ? 这是一个老生常谈的话题(This is an o...

Java中的String为什么是不可变的? -- String源码分析

什么是不可变对象? 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不...

深入理解String为什么是不可变的类

如上图所示 String s1="abcd" ;    等价于  String s1=new String("abcd"); 两个变量都指向同一个堆内存 String s="abcd";...

十大常见Java String问题

翻译人员: 铁锚 翻译时间: 2013年11月7日 原文链接: Top 10 questions of Java Strings 本文介绍Java中关于String最常见的10个问题: 1. 字...

Java的String类不可变的好处

java String类为什么不可变

Java的String类为什么是不可变的以及字符串常量池

JAVA中的String是一个不可变(immutable)类,即创建一个String对象后,是不能直接改变字符串中的某个字符的。 我们打开JDK中String类的源代码来看一下: /** The ...

Java的string类为什么是不可变的

答案一: 最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immut...

Java中的String对象是不可变的吗?(jdk7u4测试)

Java中的String对象是不可变的吗 2014-02-17 夏千林 译 ImportNew 有个仁兄在 StackOverflow 上发起了一个问题,是这么问的: 众所周知Jav...

在java中,String为什么是不可变的类?

1.”不可变的一个例子”给一个已有字符串”abcd”第二次赋值成”abcedl”,不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。

Java String不可变

String是否相等==判断的是对象的内存起始地址是否相同,equals判断自定义的语义是否相同 JVM为了提高内存效率,将所有不可变的字符串缓存在常量池中,当有新的不可变的字符串需要创建时,如果常量...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)