当程序状态不断变化时,不可变对象的有用性

我知道不可变对象总是具有相同的状态,即实际创建它们的状态。 它们的不变量是由构造函数建立的,因为它们的状态在构造之后不会改变,所以这些不变量总是保持良好状态,这就是为什么它们在multithreading环境中发布是安全的。 这一切都很好但是因为我们生活在一个动态的世界中,程序的状态不断变化,如果我们通过不可变对象构造程序的状态,这些对象会给我们带来什么好处呢?

“这些物品给我们带来了什么好处”你已经回答过了。

关于问题的“动态”部分,如果需要“更改”不可变对象,可以从旧对象创建一个新对象:

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

如果您发现重复这样做,那么您可能需要使对象变为可变并添加能够在并发环境中使用该对象所需的相关踏板安全function。

不可变对象允许您干净地将状态更改传递给不同的线程。

使用不可变对象来表示线程之间交换的消息是一种很好的做法。 一旦发送此类消息,就无法更改其有效负载,这可以防止许多与并发相关的错误。 如果线程需要进行一些进一步的更改,它只会发送下一条消息。

当你需要一些状态永不改变的静态对象时, Immutable objects非常有用。最大的优点是不变性,对象语义和智能指针使对象所有权成为一个没有实际意义的点。 隐含地,这也意味着存在并发性时的确定性行为。

Java已经定义了一些像String Integer这样的不可变类。

其他好处是它们总是具有“失败primefaces性”(Joshua Bloch使用的术语):如果不可变对象抛出exception,它永远不会处于不合需要或不确定的状态。

假设您拥有国家/地区代码等静态对象的全局缓存,可以在此处应用Immutability

为什么我们需要不可变的类?

使用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 } 

这允许复杂的数据(甚至是简单的数据,这种情况)必须是一致的(如果不是最新的)最新的,并且以非常快速和线程安全的方式传递给任何想要它的人。 传递的数据很快就会过时,但它在调用方法期间保持其值并保持一致。