我知道,与可变对象相比,不可变对象提供了几个优点,比如它们比可变对象更容易推理,它们没有复杂的状态空间,随着时间的推移而变化,我们可以自由地传递它们,它们可以制造安全的哈希表密钥等等--我的问题是,不变对象的缺点是什么?
发布于 2015-12-29 09:33:59
引用有效Java
不可变类的唯一真正缺点是它们需要为每个不同的值设置一个单独的对象。创建这些对象可能代价高昂,特别是如果它们很大的话。例如,假设您有一个百万位的BigInteger,并且要更改它的低阶位:
BigInteger moby = ...;
moby = moby.flipBit(0);flipBit方法创建一个新的
BigInteger实例,该实例也有一百万位长,仅在一个位内与原始实例不同。该操作需要与BigInteger大小成比例的时间和空间。将此与java.util.BitSet对比。与BigInteger一样,BitSet表示任意长的位序列,但与BigInteger不同,BitSet是可变的。BitSet类提供了一种方法,允许您在恒定时间内更改百万位实例的单个比特的状态。
阅读项目15:尽量减少易变性的全文
发布于 2015-12-29 09:41:40
除了可能的性能缺陷(可能!)由于GC和HotSpot优化的复杂性,不可变的结构不一定会变慢)--一个缺点是,状态现在必须在整个应用程序中线程化。对于简单的应用程序或小型脚本,以这种方式维护状态的努力可能太高,无法为您购买并发安全性。
例如,想想像Swing这样的GUI框架。绝对有可能完全使用不变的结构和一个主要的“不安全”外部循环来编写GUI框架,我想这是在Haskell中完成的。一些维护嵌套不变状态的问题可以通过镜头来解决。但是管理所有的交互(注册监听器等等)可能会涉及到很多问题,所以您可能需要引入新的抽象,比如功能反应或混合反应GUI。
基本上,当OO的封装变得不可变时,就会丢失一些OO的封装,当这成为一个问题时,就会有其他的方法,比如参与者或STM。
发布于 2015-12-30 04:53:26
我每天都和Scala一起工作。众所周知,不变性具有某些关键优势。然而,在某些情况下,允许可变的内容有时很简单。下面是一个人为的例子:
var counter = 0
something.map {e =>
...
counter += 1
}当然,我可以让映射返回一个包含有效载荷和计数的元组,或者在可用的情况下使用collection.size。但在这种情况下,可变计数器可以说是更清晰的。总的来说,我更喜欢不变性,但也允许自己做出例外。
https://stackoverflow.com/questions/34507864
复制相似问题