Java String 設計爲不可變類型的好處

原作地址:http://my.oschina.net/jasonultimate/blog/166939


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設計爲不可變的各種原因:

同步

1. 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.

1. “使用不可變的對象”是一個最佳實踐,很多地方包括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. 在程序中正確地使用不可變對象反而會使應用更加穩定。

性能

2. 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.

2.字符串不可變的第二個原因也可以理解爲是字符串不可變的結果。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被設計成不可變的原因。既然字符串字面量可以被重複使用,那麼對於字符串的修改也就是不被允許的。如果對於字符串字面量的修改是被允許的,那麼字符串將不能再被重用因爲它的內容已經被其他引用變量修改過了。

性能

3. 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.

3.在哈希Map中使用最多的Key值就是字符串對象。每次當一個字符串被基於Hash算法的集合類所引用的時候,它的Hash值都將被計算出來。Hash值的結果取決於包含在字符串中的各個字符。如果字符串中的字符可以被改變,那麼字符串的Hash值也將隨着字符的改變而改變。通過將String設計成不可變的,就保證了當字符串在內存中被創建之後,它的hash值就不會發生改變。這樣就使得Hash值可以被作爲成員變量緩存起來,一旦一個字符串對象的Hash值被計算出來,而且被作爲字符串的內部變量,那麼下一次需要使用Hash值的時候就可以無需進行額外的計算就返回同樣的值。

安全

4. 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.

4.在安全方面將String設計成不可變的原因就是String被用來進行文件操作,內存管理和網絡操作。如果字符串可以被修改,那麼很多屬性都將可能被惡意修改。

簡單

5. 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.

5.另一個將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.安全,因爲很多操作都是以字符串作爲參數的,字符串如果可以修改,那麼在我們操作的過程中如果有人對字符串進行了修改,那麼我們將得不到正確的結果。

總之呢:這樣設計只有最初的Java的開發人員才能說明白,我們只需要知道這樣設計的好處就可以了,當然,上面的也不一定全面,如果你有其他原因,請留言吧~~


參考資料:

(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章