2012-07-02 57 views
1

我知道不可變對象總是具有相同的狀態,它們是實際創建的狀態。它們的不變式由構造函數建立,並且由於它們的狀態在構建之後不會改變,所以這些不變量總是保持良好,這就是爲什麼它們可以安全地在多線程環境中發佈的原因。這一切都很好,但是因爲我們生活在一個動態的世界中,程序狀態不斷變化,所以如果我們通過不可變的對象構造我們的程序狀態,這些對象會給我們帶來什麼好處?當程序狀態不斷變化時不可變對象的用處

+0

這裏是另一篇文章,可能有你的問題的答案:http://stackoverflow.com/questions/214714/mutablevs-immutable-objects –

+0

不變的對象就像事實。事實不會改變,但你總是可以'製造'新的。 – Stefan

回答

3

「這樣的物體給我們帶來了什麼好處」,您已經回答了這個問題。

關於你的問題的「動態」的一部分,如果你需要「變革」不可變對象,你可以創建一個從舊的一個新問題:

Immutable oldObj = new Immutable(...); 
Immutable newObj = new Immutable(oldObj.property1, "a new value for property 2"); 

如果你發現你繼續做反覆,那麼也許你需要使對象變爲可變的,並添加需要能夠在併發環境中使用該對象的相關胎面安全功能。

0

Immutable objects當你需要一些靜態對象,它的狀態永不改變時,它是非常有用的。最大的優點是不變性,對象語義和智能指針使對象所有權成爲一個爭論點。隱含地,這也意味着存在併發時的確定性行爲。

的Java已經定義了一些不可改變的類,如StringInteger

其他好處是它們總是具有「失敗原子性」(Joshua Bloch使用的一個術語):如果一個不可變對象拋出一個異常,它永遠不會處於不受歡迎或不確定的狀態。如果你有一個像國家代碼靜態對象的全局緩存

讓說,在這裏你可以申請Immutability

Why do we need immutable class?

+0

不僅不可變對象本身具有失敗的原子性,而且這種原子性通常延伸到這些對象的可變持有者。如果我'Fnord'是一個不可變的類,並且一個對象具有該類類型的字段'foo',那麼就像'foo = foo.WithWizzleAndWozzle(5,3);'[這應該有效地改變'foo的值.Wizzle'設置爲5,'foo.Wozzle'設爲3]可以改變兩個值,也可以不改變。如果不改變另一個,就無法改變它。 – supercat

2

不可變對象讓你清晰地傳達狀態變化到不同的線程。

它是使用不可變對象來表示線程之間交換的消息一個好的做法。一旦發送了這樣的消息,其有效負載就不能被改變,從而防止了許多併發相關的錯誤。如果一個線程需要傳達一些進一步的變化,它只會發送下一個消息。

0

不可變對象是在這樣的情況下非常有用,用一個String對象:

public class A { 
    private volatile String currentName = "The First Name"; 

    public String getCurrentName() { 
     // Fast: no synching or blocking! Can be called billions of times by 
     // billions of threads with no trouble. 
     // (Does need to be read from memory always because it's volatile.) 
     return currentName; 
    } 
    public whatever someMethod() { 
     ... code ... 
     // Simple assignment in this case. Could involve synchronization 
     // and lots of calculations, but it's called a lot less than 
     // getCurrentName(). 
     currentName = newName; 
     ... code ... 
    } 
} 
public class B { 
     ... in some method ... 
     A objA = something; 
     // Gets "name" fast despite a billion other threads doing the same thing. 
     String name = objA.getCurrentName(); 
     // From this point on, String referenced by "name" won't change 
     // regardless of how many times A.currentName changes. 
     ... code with frequent references to objA 
} 

這使得複雜的數據(或者甚至是簡單的數據,這種情況下),必須是一致的(如果不是正好先進-date)被更新並以線程安全的方式非常快速地傳遞給任何想要它的人。數據傳輸很快變得過時,也許,但調用方法時它保持其價值,並保持一致。