不可变对象的缺点

Aam*_*mir 3 scala immutability

我知道Immutable对象比可变对象提供了几个优点,比起它们比可变对象更易于推理,它们没有随时间变化的复杂状态空间,我们可以自由地传递它们,它们可以制作安全的哈希表键等.所以我的问题是不可变对象的缺点是什么?

Ali*_*ani 6

引自Effective Java:

不可变类的唯一真正缺点是它们需要为每个不同的值分别使用一个对象.创建这些对象可能成本很高,尤其是在它们很大的情况下.例如,假设您有一个百万位的BigInteger并且您想要更改其低位:

BigInteger moby = ...; 
moby = moby.flipBit(0);
Run Code Online (Sandbox Code Playgroud)

flipBit方法创建一个新的BigInteger实例,也是一百万位长,只与一位不同.该操作需要时间和空间与大小成比例BigInteger.对比这个 java.util.BitSet.类似BigInteger,BitSet表示任意长的位序列,但不同BigInteger,BitSet是可变的.本 BitSet类提供了一种方法,可以让你改变在常数时间内millionbit实例的单位的状态.

阅读第15项:最小化可变性的完整项目


0__*_*0__ 5

除了可能的性能缺陷(可能!因为 GC 和 HotSpot 优化的复杂性,不可变结构不一定更慢) - 一个缺陷可能是现在必须在整个应用程序中线程化状态。对于简单的应用程序或小脚本,以这种方式维护状态的工作量可能太高,无法为您购买并发安全性。

例如,想想像 Swing 这样的 GUI 框架。完全可以使用不可变结构和一个主要的“不安全”外循环来编写 GUI 框架,我猜这已经在 Haskell 中完成了。例如,可以使用镜头解决维护嵌套不可变状态的一些问题。但是管理所有交互(注册侦听器等)可能会非常复杂,因此您可能想要引入新的抽象,例如功能反应式或混合反应式 GUI。

基本上你会因为全部不可变而失去一些 OO 的封装,当这成为一个问题时,有替代方法,例如 actor 或 STM。