Java中的不可靠性

Roa*_*oam 8 java immutability

我试图把事情放在"不变性"的定义中.

这里的第(3)项是作为创建不可变对象的规则之一,

不要允许子类重写方法.最简单的方法是将类声明为final....

重写的方法在子类的实例上运行.而且,据我所知,一个不可变类是一个对象在实例化后被"雕刻"在内存中的一个 - 它的成员都没有,因此对象不能被改变.

把这些放在一起 - "不可变"的定义是否适用于类和对象?通过最终确定方法,我阻止其方法在扩展类时被覆盖.我没有看到如何最终确定不可变类的方法进一步增加使其对象不可变.

JB *_*zet 7

如果您将类记录为不可变类,则此类的用户可以安全地假设此类的任何实例都是不可变的.

问题是如果你允许你的类被子类化,没有什么禁止子类添加可变状态和方法,甚至覆盖方法并使它们改变这个新状态.因此,该类用户的假设崩溃了.让课程最终成为不可能.

  • 好吧,你引用了文档的摘录,告诉我们不可变的类应该是最终的.我在解释原因.文档没有告诉make*methods*final.如果课程是最终的,那么让它们成为最终是多余的.所以,如果你问"我为什么要让方法最终?",我的回答是,正如文档所说:不要.让你的*等级*最终. (2认同)
  • 你所描述的是通常表达的智慧,但我并不完全同意.当然,合同指定它是不可变的类的子类可能会违反该合同,但任何可继承类的*any*合同都是如此.在许多情况下,不可变类允许子类没有逻辑上的原因(尽管对于各种类都是如此 - 不仅仅是不可变类),但是在很多情况下子类化是合理且有用的(对于不可变类以及可变类). (2认同)
  • @JBNizet:如果没有理由让不可变类允许子类化,那么密封它可能是好事.另一方面,还有其他适合继承的情况,例如ImmutableShape类.应该在有意义的地方使用继承和继承性,而不是在它们没有的地方,无论类是否可变.顺便说一句,我希望人们只有当它们真正意味着不可变时才会使用"不可变",而当它们实际上意味着"只读"时,它们只会使用"只读".它们是根本不同的概念. (2认同)

Sam*_*Sam 1

关键字的应用存在很大差异final

器具...

  • ...禁止子类化(因此,方法也覆盖)
  • ...方法禁止方法覆盖
  • ...实例变量确保了这些字段的不变性,因此也确保了整个对象的不变性(如果为所有对象指定),因为最终变量只能在构造时写入一次。

文件: