我知道不可變對象總是具有相同的狀態,它們是實際創建的狀態。它們的不變式由構造函數建立,並且由於它們的狀態在構建之後不會改變,所以這些不變量總是保持良好,這就是爲什麼它們可以安全地在多線程環境中發佈的原因。這一切都很好,但是因爲我們生活在一個動態的世界中,程序狀態不斷變化,所以如果我們通過不可變的對象構造我們的程序狀態,這些對象會給我們帶來什麼好處?當程序狀態不斷變化時不可變對象的用處
回答
「這樣的物體給我們帶來了什麼好處」,您已經回答了這個問題。
關於你的問題的「動態」的一部分,如果你需要「變革」不可變對象,你可以創建一個從舊的一個新問題:
Immutable oldObj = new Immutable(...);
Immutable newObj = new Immutable(oldObj.property1, "a new value for property 2");
如果你發現你繼續做反覆,那麼也許你需要使對象變爲可變的,並添加需要能夠在併發環境中使用該對象的相關胎面安全功能。
Immutable objects
當你需要一些靜態對象,它的狀態永不改變時,它是非常有用的。最大的優點是不變性,對象語義和智能指針使對象所有權成爲一個爭論點。隱含地,這也意味着存在併發時的確定性行爲。
的Java已經定義了一些不可改變的類,如String
Integer
。
其他好處是它們總是具有「失敗原子性」(Joshua Bloch使用的一個術語):如果一個不可變對象拋出一個異常,它永遠不會處於不受歡迎或不確定的狀態。如果你有一個像國家代碼靜態對象的全局緩存
讓說,在這裏你可以申請Immutability
。
不僅不可變對象本身具有失敗的原子性,而且這種原子性通常延伸到這些對象的可變持有者。如果我'Fnord'是一個不可變的類,並且一個對象具有該類類型的字段'foo',那麼就像'foo = foo.WithWizzleAndWozzle(5,3);'[這應該有效地改變'foo的值.Wizzle'設置爲5,'foo.Wozzle'設爲3]可以改變兩個值,也可以不改變。如果不改變另一個,就無法改變它。 – supercat
不可變對象讓你清晰地傳達狀態變化到不同的線程。
它是使用不可變對象來表示線程之間交換的消息一個好的做法。一旦發送了這樣的消息,其有效負載就不能被改變,從而防止了許多併發相關的錯誤。如果一個線程需要傳達一些進一步的變化,它只會發送下一個消息。
不可變對象是在這樣的情況下非常有用,用一個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)被更新並以線程安全的方式非常快速地傳遞給任何想要它的人。數據傳輸將很快變得過時,也許,但調用方法時它將保持其價值,並保持一致。
- 1. 變化狀態的對象
- 2. @Output不斷變化的布爾狀態
- 3. 用不可變對象模擬繼承+可變狀態
- 4. 序列化和不可變的對象
- 5. 如何使對象的靜態變量不可變對象B上的狀態變化
- 6. 當對象狀態發生變化時調用方法
- 7. 飛鏢序列化不可變對象
- 8. 不斷變化的類的源代碼序列化對象
- 9. 反序列化不斷變化的JSON對象名稱在C#
- 10. 當父母狀態發生變化時,孩子是否可以自動處理項目狀態變化
- 11. 如何處理在Python中不斷變化的對象字典?
- 12. 排序對象的ArrayList,但排序鍵不斷變化
- 13. 狀態變化時針不更新
- 14. URL變化不觸發對角UI路由器狀態變化
- 15. 實例化不可變配對對象
- 16. 優化的不可變對象
- 17. py.test:嘲諷不斷變化的日期時間對象
- 18. 線程變量不斷變化
- 19. 當狀態發生變化時,反應className不更新
- 20. 如何從狀態對象本身不改變狀態?
- 21. Java是否優化不可變對象?
- 22. 當線程處於活動狀態時(Runnable)狀態不正常
- 23. 當應用程序變爲活動狀態時,didUpdateLocations中的Exc_bad_acces
- 24. 數不斷變化
- 25. 不斷變化頁
- 26. CL_KERNEL_WORK_GROUP_SIZE不斷變化
- 27. 是不斷變化
- 28. ReactJS - 當子狀態發生變化時更新父狀態
- 29. 組件不聽MainApp的狀態變化
- 30. 處理ReactJs中的狀態變化
這裏是另一篇文章,可能有你的問題的答案:http://stackoverflow.com/questions/214714/mutablevs-immutable-objects –
不變的對象就像事實。事實不會改變,但你總是可以'製造'新的。 – Stefan