我已经阅读了很多地方,其中写到 java 中的不变性是一个理想的特性。为什么会这样?
5 回答
不变性使推理对象的生命周期变得更容易。它在多线程程序中特别有用,因为它使线程之间的共享变得更加简单。
一些数据结构假定键或元素是不可变的,或者没有以关键方式改变。例如地图和集合。它们不必是严格不可变的,但如果它们是,它会更容易。
不可变对象的缺点是它使回收它们变得更加困难,并且会显着影响性能。
简而言之,如果性能是一个问题,请考虑可变对象,如果不尽可能使用不可变对象。
不变性的主要好处是不能“从你下面”改变一个对象。例如,考虑一个作为 Map 键的字符串。如果它是可变的,那么可以插入一个键/值对,然后修改作为键的字符串。这会破坏映射中使用的哈希方案,并导致一些潜在的非常不可预测的操作。
在某些情况下,由于故意滥用,这种可变性可能会导致安全漏洞,但更常见的是它只会导致神秘的错误。并且“防御性”复制可变对象(以避免此类错误)将导致创建更多对象(特别是如果对问题采取公式化方法)。
(另一方面,创建了很多对象,例如,因为当有人附加到字符串时会创建一个新字符串,或者“砍掉”它的一部分,而不是简单地改变现有的字符串,所以这两种方法最终都会导致由于不同的原因,要创建更多的对象。)
当您需要知道某个类在您不期望的情况下没有更改时,非常需要不可变性。考虑哈希映射中的键。如果为某个键设置了一个可变对象,然后将其存储在该键的当前哈希值(mod 哈希数组大小)中,当您更改它时会发生什么?哈希发生变化,突然它在错误的位置!你(HashMap)不知道它已经改变了,所以你不知道要更新它的位置,所以下次有人试图查找那个键时,你就找不到它了。不变性消除了这个问题——如果你根据它的哈希把一个对象放在某个地方,你就知道它总是在你期望的地方。
而且,正如在其他地方指出的那样,不可变意味着在不同步的情况下从多个线程并发读取是安全的。
在编程中,不可变的类或对象是一个对象,其状态在创建后就不能修改。在某些情况下,即使您可以更改它们的属性(字段),它们仍然被认为是不可变的,但对象性质保持不变。
通常需要不可变对象,原因有 3 个:
- 线程安全
- 比可变对象更高的安全性
- 简单
有一个参考。您可以查看以更好地了解 Java 类和对象的不变性
Effective Java Item 15不可变类比可变类更容易设计、实现和使用。它们更不容易出错并且更安全。