1

今天,当我阅读有关 BigDecimal 类的一些文档时,我偶然发现了一个基本属性,BigDecimal 类是不可变的。

我如何向祖母解释不变性概念?

类的不变性的优缺点是什么?

扩展类可以变得可变吗?

考虑到我想用我的班级扩展 BigDecimal:

`MyBigDecimal extends BigDecimal` 

扩展是否违反了基本的面向对象设计原则?

4

4 回答 4

9

我如何向祖母解释不变性概念?

检查这个问题:什么是不可变的意思

或来自有效的 Java:

不可变类是不能修改其实例的类。每个实例中包含的所有信息都是在创建时提供的,并且在对象的生命周期内是固定的。


类的不变性的优缺点是什么?

优点:

  • 更容易推断对象的状态,因为只有一个,即在初始化时建立的状态
  • 推论:不可变对象在并发编程中更容易使用,其中状态就是一切

缺点:

  • 当您想更改对象的属性时,您需要创建一个新的 = 昂贵
  • 构造可能更复杂(cf builder 模式)

扩展类可以变得可变吗?

是的 - 这就是为什么不可变类应该成为最终类的原因(或者,将所有构造函数设为私有并提供工厂来创建新对象)。

BigDecimal 是创建不可变类时不应做的一个很好的例子(它可以扩展,这可能会导致您在问题中提到的问题)。

于 2012-07-17T10:30:17.220 回答
3

一个实例永远不会改变的不可变类。对象的状态是在构造时定义的,之后永远不会改变。

为了正确地不可变,该类不提供任何方式(除了反射)来改变其状态:没有设置方法,没有改变其内部状态的方法,没有允许访问它持有的可变字段的方法。它也应该是最终的(BigDecimal 应该是),以防止任何其他类扩展它,从而通过添加可变字段使其可变。

优点很多:

  • 类很容易理解
  • 实例本质上是线程安全的
  • 可以缓存实例而不需要从缓存中返回副本
  • 实例可以用作 Map 中的键,而不必担心之后被更改

它不违反 OO 原则:相反,状态完全封装在对象中。

注意:一些不可变对象在内部改变它们的状态(例如一些字段的延迟初始化),而不影响对象的外部可见状态。如果处理得当,它不会改变不可变对象的线程安全性。如果操作不正确,可能会使它们成为非线程安全的。

于 2012-07-17T10:32:02.500 回答
3

BigDecimal 是一个值类。它代表了来自“现实世界”的价值。让我们以整数为例。42 的值始终为 42。它的状态不能更改。如果我想要 43,它不是 42 的更改值,而是 43 的值。这个抽象的值概念通过使用不可变类在面向对象的世界中传递。如果您想向现有的数字添加一个数字,它不会更改,但会创建一个包含结果的新不可变对象。

于 2012-07-17T10:32:52.413 回答
1

类的不变性意味着如果创建了对象,则无法更改其内容。

考虑例如

String str = "Hello"; // you can not change content Hello to any other string

优点和缺点 immutability of a class-优点。/缺点。不变性与可变性

扩展类可以变得可变吗?

是的,你可以做到。

MyBigDecimal extends BigDecimal

你能做到BigDecimal的不是最终的。

于 2012-07-17T10:29:21.860 回答