我知道不可变对象总是具有相同的状态,它们是实际创建的状态。它们的不变式由构造函数建立,并且由于它们的状态在构建之后不会改变,所以这些不变量总是保持良好,这就是为什么它们可以安全地在多线程环境中发布的原因。这一切都很好,但是因为我们生活在一个动态的世界中,程序状态不断变化,所以如果我们通过不可变的对象构造我们的程序状态,这些对象会给我们带来什么好处?当程序状态不断变化时不可变对象的用处
回答
“这样的物体给我们带来了什么好处”,您已经回答了这个问题。
关于你的问题的“动态”的一部分,如果你需要“变革”不可变对象,你可以创建一个从旧的一个新问题:
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