There are many reasons due to the string class has been made immutable in Java. These reasons in view, concurrency issues, security issues and performance issues. Here is a list of various valid reasons to go for immutable string class:

String在Java中被设计成不可变的是出于很多方面的考虑. 这么做主要是针对并发问题,安全问题和性能问题。下面列出了将String设计为不可变的各种原因:

同步

. The use of immutability is a best practice and has been recommended by many sources including effective Java and official Oracle Java tutorials. The property of the object is that none of the member variables that object can be changed as they are marked as private and final. This property becomes an advantage in case of multi-threaded applications. Since the updating of the String object is not allowed, multiple threads cannot run in to synchronization issues which occur when one object updates the state of object while the other was reading the object.

. “使用不可变的对象”是一个最佳实践,很多地方包括Effective Java(是一本书)和Oracle官方的教程都推荐使用这个准则. 不可变对象的所有成员变量都是不可变的,因为它们被设置成了private和final的. 在多线程环境中,这样的属性成了一个很大的优势. 由于对于String对象的修改操作是不允许的, 多线程环境中就不会遇到同步的麻烦,比如:一个线程正在更新数据而另一个线程正在读取数据.

The official Oracle Java tutorial says that developers should not have any doubt by using immutability. Usually developers think that by having immutability the number of objects in the memory will increase because instead of updating an object, a new object has to be created. But in reality this is balanced off by the reduction in garbage collector execution. If properly used immutability can make an application more stable.

Oracle的官方教程说:开发人员在使用不可变对象的时候不应该有任何疑虑.通常开发者们会认为内存中不可变对象的数量会越来越多因为对于一个对象的更改并不是真正的修改该对象,而是产生新的对象. But in reality this is balanced off by the reduction in garbage collector execution. 在程序中正确地使用不可变对象反而会使应用更加稳定。

性能

. The second reason why string class is immutable in Java is both a cause as well as effect of string being immutable. Strings in Java in implement the fly weight design pattern and the result is string literal pool. This literal pool has the property that if string literal is already present in the literal pool then it will be reused every-time a string reference variable is initialized to a string literal with the same characters.

.字符串不可变的第二个原因也可以理解为是字符串不可变的结果。Java中字符串实现的是享元模式,这就导致了字符串缓冲池的出现,字符串缓冲池的特点就是,如果一个字符串字面量已经在缓冲池中存在了,那么每次当一个字符串引用比那辆使用相同的字面值初始化的时候,这个字面量都将被重复使用。

The requirement for having a string literal pool arises from the fact that string class is immutable in Java. Imagine a scenario where millions of string objects have been created with same characters just because the new operator always creates and returns a new instance of the class and we cannot modify a string object once it has been created. The above scenario will result in performance issues. To avoid these performance issue, string literal pool has been introduced in Java.

字符串缓冲池的产生也是基于String在Java中是不可变的这个事实。假设一个场景:数十万计的具有相同字符的字符串对象被创建,而这仅仅是因为new操作符总是创建并返回一个新的字符串实例,而且创建后的每个字符串都不能被修改。这样的场景下将导致性能问题。为了避免这些性能问题,Java就引入了字符串缓冲池。

Now let us see why string literal pool is a cause for making string class immutable in Java. Since the string literals have to be reused, updating the contents of these objects should not be allowed. Had updating of string literals been allowed, a string literal may not be reused because its contents have been changed by another reference variable.

现在让我们看看为什么字符串缓冲池也是促使String被设计成不可变的原因。既然字符串字面量可以被重复使用,那么对于字符串的修改也就是不被允许的。如果对于字符串字面量的修改是被允许的,那么字符串将不能再被重用因为它的内容已经被其他引用变量修改过了。

性能

. The most used key object for hash map is the string object. Every time a string is referenced in hash based collections classes, it’s hash code is calculated. The hash code of string objects depends upon the characters contained in that string. If the characters of a string object were allowed to be changed, the hash code of that string object will change when the characters of the string change. By making string class immutable in Java, it has been insured that the hash code of string object will not change after the string object has been created in the memory. More over, this allows the hash code to be cached as a member variable. Once the hash code has been calculated for a string object and is told as the value of this internal member variable, the same can be returned next time without the need for performing any calculation.

.在哈希Map中使用最多的Key值就是字符串对象。每次当一个字符串被基于Hash算法的集合类所引用的时候,它的Hash值都将被计算出来。Hash值的结果取决于包含在字符串中的各个字符。如果字符串中的字符可以被改变,那么字符串的Hash值也将随着字符的改变而改变。通过将String设计成不可变的,就保证了当字符串在内存中被创建之后,它的hash值就不会发生改变。这样就使得Hash值可以被作为成员变量缓存起来,一旦一个字符串对象的Hash值被计算出来,而且被作为字符串的内部变量,那么下一次需要使用Hash值的时候就可以无需进行额外的计算就返回同样的值。

安全

. The security aspect of having the string class immutable in Java is that strings are used for file operations, memory management and network operations. If strings are allowed to be mutable, various properties could be changed in malicious ways.

.在安全方面将String设计成不可变的原因就是String被用来进行文件操作,内存管理和网络操作。如果字符串可以被修改,那么很多属性都将可能被恶意修改。

简单

. Another reason to make the string class mutable is the simplicity aspect. Though for beginners it is a learning curve to understand the behavior of string objects but once they understand, it is very easy to visualize the behavior of string objects in any particular scenario. Allowing the updating of string objects would have made it more complex to understand the behavior of strings.

.另一个将String设计成不可变的原因就是出于简单方面的考虑。尽管对于初学者来说理解字符串对象的行为是比较有难度的,但一旦他们理解了,在任何特殊的场景下理解字符串对象的行为就变得很容易了。而将字符串设计成可变的将使得这个理解的过程更加复杂。

The point to note about the design decision is that the advantages of making string class immutable are more than not making it immutable.

注意:这样设计的原因就是String不可变比String可变具有更多的优势。

========个人总结=========

之所以将String设计成为Immutable的,这是由String的作用所决定的。

1.这样可以解决同步安全问题。

2.设计成不可变的就会导致性能下降,因为每次修改都将产生新的对象,而字符串缓冲池很好的解决了这个问题。

3.安全,因为很多操作都是以字符串作为参数的,字符串如果可以修改,那么在我们操作的过程中如果有人对字符串进行了修改,那么我们将得不到正确的结果。

参考资料:

(1)http://www.javaexperience.com/why-the-string-class-is-immutable/#ixzz2grdKUGIh

(2)http://javarevisited.blogspot.com/2010/10/why-string-is-immutable-in-java.html

04-23 13:10