为什么Java中的BigInteger被设计为不可变的?

2022-09-04 20:06:07

在java中,BigInteger是不可变的,但我想了解为什么,因为很多时候它被用来做很多计算,可以产生很多对象。所以,感觉有点直观,不让它不可变。我想到的情况是字符串操作,然后是StringBuilder的选项。应该有BigInteger的非不变对应物吗?我认为这在很多情况下可能是有益的。

编辑:我知道不变性的好处以及它在很多情况下的益处。我只是想了解W.r.t BigInteger的好处。我使用 BigInteger 来计算大数的阶乘。所以,我更喜欢一个可变的BigInteger。类似地,BigInteger将用于计算结果远大于int。对于其他情况,有BigDecimal。


答案 1

Josh Bloch 的 Effective Java 在“Item 15: Minimize Mutability”中解释了不可变类的好处:

不可变类比可变类更易于设计、实现和使用。它们不易出错,更安全。

不可变对象很简单,因为对象只能存在于一个状态中 - 创建它的状态。简单代码往往具有较少的错误。由于无法修改该对象,因此它也是线程安全的,无需外部同步。

Bloch 解决了不可变类的性能问题,例如:BigInteger

不可变类的唯一真正缺点是它们需要为每个不同的值使用单独的对象。创建这些对象可能代价高昂,尤其是当它们很大时。[...]

在内部,不可变类可以任意聪明。例如,BigInteger 有一个包私有可变“伴随类”,它用它来加速多步运算,如模幂。由于前面概述的所有原因,使用可变伴随类比使用BigInteger要困难得多,但幸运的是您不必这样做:BigInteger的实现者为您做了艰苦的工作。

因此,在内部,已经为您进行了一些优化。如果你真的想要一个可变的,你可以使用BitSet,但请注意,这可能会使你的代码更复杂 - 并且更容易出错。您应该使用最简单的解决方案(),除非您确信使用可变版本会给您带来明显的性能提升(另请参阅同一本书中的“项目55:明智地优化”)。BigIntegerBigIntegerBigInteger


答案 2